blob: 40989b29995e68b7e58d20b3aed478cc9c4b81e3 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 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 */
Ian Rogersb033c752011-07-20 12:22:35 -070016
Ian Rogers700a4022014-05-19 16:49:03 -070017#include <memory>
Igor Murashkin367f3dd2016-09-01 17:00:24 -070018#include <type_traits>
Ian Rogers700a4022014-05-19 16:49:03 -070019
Nicolas Geoffray54accbc2014-08-13 03:40:45 +010020#include <math.h>
21
Mathieu Chartiere401d142015-04-22 13:56:20 -070022#include "art_method-inl.h"
Pavle Batuta837e72a2016-03-16 11:31:46 +010023#include "base/bit_utils.h"
Vladimir Markocedec9d2021-02-08 16:16:13 +000024#include "base/casts.h"
Vladimir Marko76e87952022-11-16 09:04:28 +000025#include "base/macros.h"
David Sehr79e26072018-04-06 17:58:50 -070026#include "base/mem_map.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070027#include "class_linker.h"
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -080028#include "common_compiler_test.h"
Igor Murashkin367f3dd2016-09-01 17:00:24 -070029#include "compiler.h"
David Sehr9e734c72018-01-04 17:56:19 -080030#include "dex/dex_file.h"
Vladimir Marko41c3de22022-12-07 15:42:12 +010031#include "driver/compiler_options.h"
Vladimir Markoce2a3442021-11-24 15:10:26 +000032#include "entrypoints/entrypoint_utils-inl.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070033#include "gtest/gtest.h"
Ian Rogerscdd1d2d2011-08-18 09:58:17 -070034#include "indirect_reference_table.h"
Vladimir Markocedec9d2021-02-08 16:16:13 +000035#include "java_frame_root_info.h"
Vladimir Markoa3ad0cd2018-05-04 10:06:38 +010036#include "jni/java_vm_ext.h"
37#include "jni/jni_internal.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070038#include "mirror/class-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080039#include "mirror/class_loader.h"
Ian Rogers04d7aa92013-03-16 14:29:17 -070040#include "mirror/object-inl.h"
Steven Morelande431e272017-07-18 16:53:49 -070041#include "mirror/object_array-inl.h"
Vladimir Markobdc93b42019-03-29 16:12:04 +000042#include "mirror/stack_trace_element-inl.h"
Steven Morelande431e272017-07-18 16:53:49 -070043#include "nativehelper/ScopedLocalRef.h"
Dimitry Ivanov5edb0632016-04-29 11:14:25 -070044#include "nativeloader/native_loader.h"
Vladimir Marko4d527152021-11-23 12:07:04 +000045#include "oat_quick_method_header.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070046#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070047#include "scoped_thread_state_change-inl.h"
Vladimir Marko7b97aeb2022-12-01 16:17:47 +000048#include "thread-inl.h"
Ian Rogersb033c752011-07-20 12:22:35 -070049
Elliott Hughesb264f082012-04-06 17:10:10 -070050extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_bar(JNIEnv*, jobject, jint count) {
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080051 return count + 1;
52}
53
Vladimir Markofa458ac2020-02-12 14:08:07 +000054// Note: JNI name mangling "_" -> "_1".
55extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_bar_1Fast(JNIEnv*, jobject, jint count) {
56 return count + 1;
57}
58
Elliott Hughesb264f082012-04-06 17:10:10 -070059extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_sbar(JNIEnv*, jclass, jint count) {
Ian Rogers1cefdbd2012-02-29 09:34:50 -080060 return count + 1;
61}
62
Vladimir Markofa458ac2020-02-12 14:08:07 +000063// Note: JNI name mangling "_" -> "_1".
64extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_sbar_1Fast(JNIEnv*, jclass, jint count) {
65 return count + 1;
66}
67
68// Note: JNI name mangling "_" -> "_1".
69extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_sbar_1Critical(jint count) {
70 return count + 1;
71}
72
Roland Levillain97c46462017-05-11 14:04:03 +010073// TODO: In the Baker read barrier configuration, add checks to ensure
74// the Marking Register's value is correct.
75
Vladimir Marko76e87952022-11-16 09:04:28 +000076namespace art HIDDEN {
Ian Rogersb033c752011-07-20 12:22:35 -070077
Igor Murashkin367f3dd2016-09-01 17:00:24 -070078enum class JniKind {
Vladimir Markob0a6aee2017-10-27 10:34:04 +010079 kNormal, // Regular kind of un-annotated natives.
80 kFast, // Native method annotated with @FastNative.
81 kCritical, // Native method annotated with @CriticalNative.
82 kCount // How many different types of JNIs we can have.
Igor Murashkin367f3dd2016-09-01 17:00:24 -070083};
84
85// Used to initialize array sizes that want to have different state per current jni.
86static constexpr size_t kJniKindCount = static_cast<size_t>(JniKind::kCount);
87// Do not use directly, use the helpers instead.
88uint32_t gCurrentJni = static_cast<uint32_t>(JniKind::kNormal);
89
90// Is the current native method under test @CriticalNative?
91static bool IsCurrentJniCritical() {
92 return gCurrentJni == static_cast<uint32_t>(JniKind::kCritical);
93}
94
Vladimir Markofa458ac2020-02-12 14:08:07 +000095// Is the current native method under test @FastNative?
96static bool IsCurrentJniFast() {
97 return gCurrentJni == static_cast<uint32_t>(JniKind::kFast);
98}
99
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700100// Is the current native method a plain-old non-annotated native?
101static bool IsCurrentJniNormal() {
102 return gCurrentJni == static_cast<uint32_t>(JniKind::kNormal);
103}
104
Roland Levillainef012222017-06-21 16:28:06 +0100105// Signify that a different kind of JNI is about to be tested.
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700106static void UpdateCurrentJni(JniKind kind) {
107 gCurrentJni = static_cast<uint32_t>(kind);
108}
109
110// (Match the name suffixes of native methods in MyClassNatives.java)
111static std::string CurrentJniStringSuffix() {
112 switch (gCurrentJni) {
113 case static_cast<uint32_t>(JniKind::kNormal): {
114 return "";
115 }
116 case static_cast<uint32_t>(JniKind::kFast): {
117 return "_Fast";
118 }
119 case static_cast<uint32_t>(JniKind::kCritical): {
120 return "_Critical";
121 }
122 default:
123 LOG(FATAL) << "Invalid current JNI value: " << gCurrentJni;
124 UNREACHABLE();
125 }
126}
127
Vladimir Markoc2208272020-07-23 11:04:39 +0000128// Fake values passed to our JNI handlers when we enter @CriticalNative.
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700129// Normally @CriticalNative calling convention strips out the "JNIEnv*, jclass" parameters.
130// However to avoid duplicating every single test method we have a templated handler
Vladimir Markoc2208272020-07-23 11:04:39 +0000131// that inserts fake parameters (0,1) to make it compatible with a regular JNI handler.
132static JNIEnv* const kCriticalFakeJniEnv = reinterpret_cast<JNIEnv*>(0xDEADFEAD);
133static jclass const kCriticalFakeJniClass = reinterpret_cast<jclass>(0xBEAFBEEF);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700134
135// Type trait. Returns true if "T" is the same type as one of the types in Args...
136//
137// Logically equal to OR(std::same_type<T, U> for all U in Args).
138template <typename T, typename ... Args>
139struct is_any_of;
140
141template <typename T, typename U, typename ... Args>
142struct is_any_of<T, U, Args ...> {
143 using value_type = bool;
144 static constexpr const bool value = std::is_same<T, U>::value || is_any_of<T, Args ...>::value;
145};
146
147template <typename T, typename U>
148struct is_any_of<T, U> {
149 using value_type = bool;
150 static constexpr const bool value = std::is_same<T, U>::value;
151};
152
153// Type traits for JNI types.
154template <typename T>
155struct jni_type_traits {
156 // True if type T ends up holding an object reference. False otherwise.
157 // (Non-JNI types will also be false).
158 static constexpr const bool is_ref =
159 is_any_of<T, jclass, jobject, jstring, jobjectArray, jintArray,
160 jcharArray, jfloatArray, jshortArray, jdoubleArray, jlongArray>::value;
161};
162
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700163// Base case: No parameters = 0 refs.
164size_t count_nonnull_refs_helper() {
165 return 0;
166}
167
168// SFINAE for ref types. 1 if non-null, 0 otherwise.
169template <typename T>
170size_t count_nonnull_refs_single_helper(T arg,
171 typename std::enable_if<jni_type_traits<T>::is_ref>::type*
172 = nullptr) {
173 return ((arg == NULL) ? 0 : 1);
174}
175
176// SFINAE for non-ref-types. Always 0.
177template <typename T>
Stefano Cianciulli78f3c722023-05-16 10:32:54 +0000178size_t count_nonnull_refs_single_helper(
179 [[maybe_unused]] T arg, typename std::enable_if<!jni_type_traits<T>::is_ref>::type* = nullptr) {
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700180 return 0;
181}
182
183// Recursive case.
184template <typename T, typename ... Args>
185size_t count_nonnull_refs_helper(T arg, Args ... args) {
186 return count_nonnull_refs_single_helper(arg) + count_nonnull_refs_helper(args...);
187}
188
189// Given any list of parameters, check how many object refs there are and only count
190// them if their runtime value is non-null.
191//
192// For example given (jobject, jint, jclass) we can get (2) if both #0/#2 are non-null,
193// (1) if either #0/#2 are null but not both, and (0) if all parameters are null.
194// Primitive parameters (including JNIEnv*, if present) are ignored.
195template <typename ... Args>
196size_t count_nonnull_refs(Args ... args) {
197 return count_nonnull_refs_helper(args...);
198}
199
Yabin Cui948f0622020-02-04 17:18:41 -0800200template <typename T, T* fn>
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700201struct remove_extra_parameters_helper;
202
Yabin Cui948f0622020-02-04 17:18:41 -0800203template <typename R, typename Arg1, typename Arg2, typename ... Args, R (*fn)(Arg1, Arg2, Args...)>
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700204struct remove_extra_parameters_helper<R(Arg1, Arg2, Args...), fn> {
205 // Note: Do not use Args&& here to maintain C-style parameter types.
206 static R apply(Args... args) {
Vladimir Markoc2208272020-07-23 11:04:39 +0000207 JNIEnv* env = kCriticalFakeJniEnv;
208 jclass kls = kCriticalFakeJniClass;
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700209 return fn(env, kls, args...);
210 }
211};
212
213// Given a function 'fn' create a function 'apply' which will omit the JNIEnv/jklass parameters
214//
215// i.e. if fn(JNIEnv*,jklass,a,b,c,d,e...) then apply(a,b,c,d,e,...)
Yabin Cui948f0622020-02-04 17:18:41 -0800216template <typename T, T* fn>
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700217struct jni_remove_extra_parameters : public remove_extra_parameters_helper<T, fn> {};
218
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -0800219class JniCompilerTest : public CommonCompilerTest {
Ian Rogersb033c752011-07-20 12:22:35 -0700220 protected:
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100221 void SetUp() override {
Andreas Gampe6e498692014-08-18 16:43:12 -0700222 CommonCompilerTest::SetUp();
223 check_generic_jni_ = false;
224 }
225
Roland Levillainbbc6e7e2018-08-24 16:58:47 +0100226 void TearDown() override {
Dimitry Ivanov5edb0632016-04-29 11:14:25 -0700227 android::ResetNativeLoader();
228 CommonCompilerTest::TearDown();
229 }
230
Andreas Gampe6e498692014-08-18 16:43:12 -0700231 void SetCheckGenericJni(bool generic) {
232 check_generic_jni_ = generic;
233 }
234
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700235 private:
236 void CompileForTest(jobject class_loader,
237 bool direct,
238 const char* method_name,
239 const char* method_sig) {
Hans Boehmba5cc5b2022-09-09 22:43:53 +0000240 Thread* self = Thread::Current();
241 ScopedObjectAccess soa(self);
242 StackHandleScope<2> hs(self);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700243 Handle<mirror::ClassLoader> loader(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700244 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Brian Carlstrom25c33252011-09-18 15:58:35 -0700245 // Compile the native method before starting the runtime
Vladimir Marko2cefb3b2021-02-22 13:32:33 +0000246 Handle<mirror::Class> c =
Hans Boehmba5cc5b2022-09-09 22:43:53 +0000247 hs.NewHandle(class_linker_->FindClass(self, "LMyClassNatives;", loader));
Mathieu Chartiere401d142015-04-22 13:56:20 -0700248 const auto pointer_size = class_linker_->GetImagePointerSize();
Vladimir Markoba118822017-06-12 15:41:56 +0100249 ArtMethod* method = c->FindClassMethod(method_name, method_sig, pointer_size);
Andreas Gampecf4035a2014-05-28 22:43:01 -0700250 ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig;
Vladimir Markoba118822017-06-12 15:41:56 +0100251 ASSERT_EQ(direct, method->IsDirect()) << method_name << " " << method_sig;
Vladimir Marko2cefb3b2021-02-22 13:32:33 +0000252 if (direct) {
253 // Class initialization could replace the entrypoint, so force
254 // the initialization before we set up the entrypoint below.
255 class_linker_->EnsureInitialized(
Hans Boehmba5cc5b2022-09-09 22:43:53 +0000256 self, c, /*can_init_fields=*/ true, /*can_init_parents=*/ true);
257 {
258 ScopedThreadSuspension sts(self, ThreadState::kNative);
259 class_linker_->MakeInitializedClassesVisiblyInitialized(self, /*wait=*/ true);
260 }
Vladimir Marko2cefb3b2021-02-22 13:32:33 +0000261 }
Andreas Gampe6e498692014-08-18 16:43:12 -0700262 if (check_generic_jni_) {
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700263 method->SetEntryPointFromQuickCompiledCode(class_linker_->GetRuntimeQuickGenericJniStub());
Nicolas Geoffray54accbc2014-08-13 03:40:45 +0100264 } else {
Ian Rogers6f3dbba2014-10-14 17:41:57 -0700265 const void* code = method->GetEntryPointFromQuickCompiledCode();
266 if (code == nullptr || class_linker_->IsQuickGenericJniStub(code)) {
Nicolas Geoffray54accbc2014-08-13 03:40:45 +0100267 CompileMethod(method);
268 ASSERT_TRUE(method->GetEntryPointFromQuickCompiledCode() != nullptr)
269 << method_name << " " << method_sig;
Nicolas Geoffray54accbc2014-08-13 03:40:45 +0100270 }
Brian Carlstrom25c33252011-09-18 15:58:35 -0700271 }
Brian Carlstrom25c33252011-09-18 15:58:35 -0700272 }
273
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700274 protected:
275 void CompileForTestWithCurrentJni(jobject class_loader,
276 bool direct,
277 const char* method_name_orig,
278 const char* method_sig) {
279 // Append the JNI kind to the method name, so that we automatically get the
280 // fast or critical versions of the same method.
281 std::string method_name_str = std::string(method_name_orig) + CurrentJniStringSuffix();
282 const char* method_name = method_name_str.c_str();
283
284 CompileForTest(class_loader, direct, method_name, method_sig);
285 }
286
287 void SetUpForTest(bool direct,
288 const char* method_name_orig,
289 const char* method_sig,
Andreas Gampe6e498692014-08-18 16:43:12 -0700290 void* native_fnptr) {
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700291 // Append the JNI kind to the method name, so that we automatically get the
292 // fast or critical versions of the same method.
293 std::string method_name_str = std::string(method_name_orig) + CurrentJniStringSuffix();
294 const char* method_name = method_name_str.c_str();
295
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700296 // Initialize class loader and compile method when runtime not started.
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700297 if (!runtime_->IsStarted()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700298 {
299 ScopedObjectAccess soa(Thread::Current());
300 class_loader_ = LoadDex("MyClassNatives");
301 }
Andreas Gampe6e498692014-08-18 16:43:12 -0700302 CompileForTest(class_loader_, direct, method_name, method_sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700303 // Start runtime.
304 Thread::Current()->TransitionFromSuspendedToRunnable();
Dimitry Ivanov5edb0632016-04-29 11:14:25 -0700305 android::InitializeNativeLoader();
Dimitry Ivanovc544f342016-05-09 16:26:13 -0700306 bool started = runtime_->Start();
Brian Carlstrombd86bcc2013-03-10 20:26:16 -0700307 CHECK(started);
Brian Carlstrom25c33252011-09-18 15:58:35 -0700308 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700309 // JNI operations after runtime start.
Brian Carlstrom25c33252011-09-18 15:58:35 -0700310 env_ = Thread::Current()->GetJniEnv();
Elliott Hughesb264f082012-04-06 17:10:10 -0700311 jklass_ = env_->FindClass("MyClassNatives");
Andreas Gampecf4035a2014-05-28 22:43:01 -0700312 ASSERT_TRUE(jklass_ != nullptr) << method_name << " " << method_sig;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700313
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700314 if (direct) {
315 jmethod_ = env_->GetStaticMethodID(jklass_, method_name, method_sig);
316 } else {
317 jmethod_ = env_->GetMethodID(jklass_, method_name, method_sig);
318 }
Andreas Gampecf4035a2014-05-28 22:43:01 -0700319 ASSERT_TRUE(jmethod_ != nullptr) << method_name << " " << method_sig;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700320
Vladimir Marko86c87522020-05-11 16:55:55 +0100321 // Make sure the test class is visibly initialized so that the RegisterNatives() below
322 // sets the JNI entrypoint rather than leaving it as null (this test pretends to be an
323 // AOT compiler and therefore the ClassLinker skips entrypoint initialization). Even
324 // if the ClassLinker initialized it with a stub, we would not want to test that here.
325 class_linker_->MakeInitializedClassesVisiblyInitialized(Thread::Current(), /*wait=*/ true);
326
Andreas Gampecf4035a2014-05-28 22:43:01 -0700327 if (native_fnptr != nullptr) {
Elliott Hughesb25c3f62012-03-26 16:35:06 -0700328 JNINativeMethod methods[] = { { method_name, method_sig, native_fnptr } };
Brian Carlstromfc7120c2012-08-27 13:43:25 -0700329 ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1))
330 << method_name << " " << method_sig;
Ian Rogersbdb03912011-09-14 00:55:44 -0700331 } else {
332 env_->UnregisterNatives(jklass_);
Shih-wei Liao31384c52011-09-06 15:27:45 -0700333 }
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700334
335 jmethodID constructor = env_->GetMethodID(jklass_, "<init>", "()V");
336 jobj_ = env_->NewObject(jklass_, constructor);
Andreas Gampecf4035a2014-05-28 22:43:01 -0700337 ASSERT_TRUE(jobj_ != nullptr) << method_name << " " << method_sig;
Ian Rogersb033c752011-07-20 12:22:35 -0700338 }
339
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700340 public:
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700341 // Available as statics so our JNI handlers can access these.
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700342 static jclass jklass_;
343 static jobject jobj_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700344 static jobject class_loader_;
345
Vladimir Markoce2a3442021-11-24 15:10:26 +0000346 static void AssertCallerObjectLocked(JNIEnv* env);
347
Vladimir Marko3a50f342021-12-03 15:55:26 +0000348 static LockWord GetLockWord(jobject obj);
349
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700350 protected:
Andreas Gampe6e498692014-08-18 16:43:12 -0700351 // We have to list the methods here so we can share them between default and generic JNI.
352 void CompileAndRunNoArgMethodImpl();
353 void CompileAndRunIntMethodThroughStubImpl();
354 void CompileAndRunStaticIntMethodThroughStubImpl();
355 void CompileAndRunIntMethodImpl();
356 void CompileAndRunIntIntMethodImpl();
357 void CompileAndRunLongLongMethodImpl();
358 void CompileAndRunDoubleDoubleMethodImpl();
359 void CompileAndRun_fooJJ_synchronizedImpl();
360 void CompileAndRunIntObjectObjectMethodImpl();
361 void CompileAndRunStaticIntIntMethodImpl();
362 void CompileAndRunStaticDoubleDoubleMethodImpl();
363 void RunStaticLogDoubleMethodImpl();
364 void RunStaticLogFloatMethodImpl();
365 void RunStaticReturnTrueImpl();
366 void RunStaticReturnFalseImpl();
367 void RunGenericStaticReturnIntImpl();
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700368 void RunGenericStaticReturnDoubleImpl();
369 void RunGenericStaticReturnLongImpl();
Andreas Gampe6e498692014-08-18 16:43:12 -0700370 void CompileAndRunStaticIntObjectObjectMethodImpl();
371 void CompileAndRunStaticSynchronizedIntObjectObjectMethodImpl();
372 void ExceptionHandlingImpl();
373 void NativeStackTraceElementImpl();
374 void ReturnGlobalRefImpl();
375 void LocalReferenceTableClearingTestImpl();
376 void JavaLangSystemArrayCopyImpl();
377 void CompareAndSwapIntImpl();
378 void GetTextImpl();
379 void GetSinkPropertiesNativeImpl();
380 void UpcallReturnTypeChecking_InstanceImpl();
381 void UpcallReturnTypeChecking_StaticImpl();
382 void UpcallArgumentTypeChecking_InstanceImpl();
383 void UpcallArgumentTypeChecking_StaticImpl();
384 void CompileAndRunFloatFloatMethodImpl();
385 void CheckParameterAlignImpl();
386 void MaxParamNumberImpl();
387 void WithoutImplementationImpl();
Andreas Gampe48ee3562015-04-10 19:57:29 -0700388 void WithoutImplementationRefReturnImpl();
Vladimir Markofa458ac2020-02-12 14:08:07 +0000389 void StaticWithoutImplementationImpl();
Andreas Gampe6e498692014-08-18 16:43:12 -0700390 void StackArgsIntsFirstImpl();
391 void StackArgsFloatsFirstImpl();
392 void StackArgsMixedImpl();
393
Igor Murashkin9d4b6da2016-07-29 09:51:58 -0700394 void NormalNativeImpl();
395 void FastNativeImpl();
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700396 void CriticalNativeImpl();
Igor Murashkin9d4b6da2016-07-29 09:51:58 -0700397
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700398 JNIEnv* env_;
399 jmethodID jmethod_;
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700400
401 private:
Andreas Gampe6e498692014-08-18 16:43:12 -0700402 bool check_generic_jni_;
Ian Rogersb033c752011-07-20 12:22:35 -0700403};
404
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700405jclass JniCompilerTest::jklass_;
406jobject JniCompilerTest::jobj_;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700407jobject JniCompilerTest::class_loader_;
Vladimir Markocedec9d2021-02-08 16:16:13 +0000408
Vladimir Markoce2a3442021-11-24 15:10:26 +0000409void JniCompilerTest::AssertCallerObjectLocked(JNIEnv* env) {
Vladimir Marko7b97aeb2022-12-01 16:17:47 +0000410 Thread* self = Thread::ForEnv(env);
Vladimir Markoce2a3442021-11-24 15:10:26 +0000411 CHECK_EQ(self, Thread::Current());
412 ScopedObjectAccess soa(self);
Vladimir Marko4d527152021-11-23 12:07:04 +0000413 ArtMethod** caller_frame = self->GetManagedStack()->GetTopQuickFrame();
414 CHECK(caller_frame != nullptr);
415 ArtMethod* caller = *caller_frame;
416 CHECK(caller != nullptr);
417 CHECK(caller->IsNative());
418 CHECK(!caller->IsFastNative());
419 CHECK(!caller->IsCriticalNative());
420 CHECK(caller->IsSynchronized());
421 ObjPtr<mirror::Object> lock;
Mythri Allec2632ac2022-05-13 14:37:52 +0000422 if (self->GetManagedStack()->GetTopQuickFrameGenericJniTag()) {
Vladimir Markoce2a3442021-11-24 15:10:26 +0000423 // Generic JNI.
424 lock = GetGenericJniSynchronizationObject(self, caller);
425 } else if (caller->IsStatic()) {
Vladimir Marko4d527152021-11-23 12:07:04 +0000426 lock = caller->GetDeclaringClass();
427 } else {
428 uint8_t* sp = reinterpret_cast<uint8_t*>(caller_frame);
429 const void* code_ptr = EntryPointToCodePointer(caller->GetEntryPointFromQuickCompiledCode());
430 OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
431 size_t frame_size = method_header->GetFrameSizeInBytes();
432 StackReference<mirror::Object>* this_ref = reinterpret_cast<StackReference<mirror::Object>*>(
433 sp + frame_size + static_cast<size_t>(kRuntimePointerSize));
434 lock = this_ref->AsMirrorPtr();
435 }
436 CHECK_EQ(Monitor::GetLockOwnerThreadId(lock), self->GetThreadId());
Vladimir Markocedec9d2021-02-08 16:16:13 +0000437}
438
Vladimir Marko3a50f342021-12-03 15:55:26 +0000439LockWord JniCompilerTest::GetLockWord(jobject obj) {
440 ScopedObjectAccess soa(Thread::Current());
441 return soa.Decode<mirror::Object>(obj)->GetLockWord(/*as_volatile=*/ false);
442}
443
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700444// Test the normal compiler and normal generic JNI only.
445// The following features are unsupported in @FastNative:
Vladimir Markofa458ac2020-02-12 14:08:07 +0000446// 1) synchronized keyword
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700447# define JNI_TEST_NORMAL_ONLY(TestName) \
Igor Murashkin06a04e02016-09-13 15:57:37 -0700448 TEST_F(JniCompilerTest, TestName ## NormalCompiler) { \
Igor Murashkina51d8b72016-10-05 14:33:30 -0700449 ScopedCheckHandleScope top_handle_scope_check; \
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700450 SCOPED_TRACE("Normal JNI with compiler"); \
451 gCurrentJni = static_cast<uint32_t>(JniKind::kNormal); \
Andreas Gampe6e498692014-08-18 16:43:12 -0700452 TestName ## Impl(); \
453 } \
Igor Murashkin06a04e02016-09-13 15:57:37 -0700454 TEST_F(JniCompilerTest, TestName ## NormalGeneric) { \
Igor Murashkina51d8b72016-10-05 14:33:30 -0700455 ScopedCheckHandleScope top_handle_scope_check; \
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700456 SCOPED_TRACE("Normal JNI with generic"); \
457 gCurrentJni = static_cast<uint32_t>(JniKind::kNormal); \
Andreas Gampe6e498692014-08-18 16:43:12 -0700458 SetCheckGenericJni(true); \
459 TestName ## Impl(); \
460 }
Andreas Gampecf4035a2014-05-28 22:43:01 -0700461
Igor Murashkin06a04e02016-09-13 15:57:37 -0700462// Test (normal, @FastNative) x (compiler, generic).
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700463#define JNI_TEST(TestName) \
464 JNI_TEST_NORMAL_ONLY(TestName) \
Igor Murashkin06a04e02016-09-13 15:57:37 -0700465 TEST_F(JniCompilerTest, TestName ## FastCompiler) { \
Igor Murashkina51d8b72016-10-05 14:33:30 -0700466 ScopedCheckHandleScope top_handle_scope_check; \
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700467 SCOPED_TRACE("@FastNative JNI with compiler"); \
468 gCurrentJni = static_cast<uint32_t>(JniKind::kFast); \
469 TestName ## Impl(); \
470 } \
Igor Murashkin06a04e02016-09-13 15:57:37 -0700471 \
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700472 TEST_F(JniCompilerTest, TestName ## FastGeneric) { \
Igor Murashkina51d8b72016-10-05 14:33:30 -0700473 ScopedCheckHandleScope top_handle_scope_check; \
Igor Murashkin06a04e02016-09-13 15:57:37 -0700474 SCOPED_TRACE("@FastNative JNI with generic"); \
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700475 gCurrentJni = static_cast<uint32_t>(JniKind::kFast); \
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700476 SetCheckGenericJni(true); \
477 TestName ## Impl(); \
478 }
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700479
Igor Murashkin06a04e02016-09-13 15:57:37 -0700480// Test (@CriticalNative) x (compiler, generic) only.
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700481#define JNI_TEST_CRITICAL_ONLY(TestName) \
Igor Murashkin06a04e02016-09-13 15:57:37 -0700482 TEST_F(JniCompilerTest, TestName ## CriticalCompiler) { \
Igor Murashkina51d8b72016-10-05 14:33:30 -0700483 ScopedCheckHandleScope top_handle_scope_check; \
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700484 SCOPED_TRACE("@CriticalNative JNI with compiler"); \
485 gCurrentJni = static_cast<uint32_t>(JniKind::kCritical); \
486 TestName ## Impl(); \
Igor Murashkin06a04e02016-09-13 15:57:37 -0700487 } \
488 TEST_F(JniCompilerTest, TestName ## CriticalGeneric) { \
Igor Murashkina51d8b72016-10-05 14:33:30 -0700489 ScopedCheckHandleScope top_handle_scope_check; \
Igor Murashkin06a04e02016-09-13 15:57:37 -0700490 SCOPED_TRACE("@CriticalNative JNI with generic"); \
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700491 gCurrentJni = static_cast<uint32_t>(JniKind::kCritical); \
Igor Murashkin294a9152016-09-28 13:23:19 -0700492 SetCheckGenericJni(true); \
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700493 TestName ## Impl(); \
494 }
Igor Murashkin06a04e02016-09-13 15:57:37 -0700495
496// Test everything: (normal, @FastNative, @CriticalNative) x (compiler, generic).
497#define JNI_TEST_CRITICAL(TestName) \
498 JNI_TEST(TestName) \
499 JNI_TEST_CRITICAL_ONLY(TestName) \
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700500
501static void expectValidThreadState() {
502 // Normal JNI always transitions to "Native". Other JNIs stay in the "Runnable" state.
503 if (IsCurrentJniNormal()) {
Vladimir Markoddf4fd32021-11-22 16:31:57 +0000504 EXPECT_EQ(ThreadState::kNative, Thread::Current()->GetState());
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700505 } else {
Vladimir Markoddf4fd32021-11-22 16:31:57 +0000506 EXPECT_EQ(ThreadState::kRunnable, Thread::Current()->GetState());
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700507 }
508}
509
510#define EXPECT_THREAD_STATE_FOR_CURRENT_JNI() expectValidThreadState()
511
512static void expectValidMutatorLockHeld() {
513 if (IsCurrentJniNormal()) {
514 Locks::mutator_lock_->AssertNotHeld(Thread::Current());
515 } else {
516 Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
517 }
518}
519
520#define EXPECT_MUTATOR_LOCK_FOR_CURRENT_JNI() expectValidMutatorLockHeld()
521
522static void expectValidJniEnvAndObject(JNIEnv* env, jobject thisObj) {
523 if (!IsCurrentJniCritical()) {
524 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
525 ASSERT_TRUE(thisObj != nullptr);
526 EXPECT_TRUE(env->IsInstanceOf(thisObj, JniCompilerTest::jklass_));
527 } else {
528 LOG(FATAL) << "Objects are not supported for @CriticalNative, why is this being tested?";
529 UNREACHABLE();
530 }
531}
532
533// Validates the JNIEnv to be the same as the current thread's JNIEnv, and makes sure
534// that the object here is an instance of the class we registered the method with.
535//
536// Hard-fails if this somehow gets invoked for @CriticalNative since objects are unsupported.
537#define EXPECT_JNI_ENV_AND_OBJECT_FOR_CURRENT_JNI(env, thisObj) \
538 expectValidJniEnvAndObject(env, thisObj)
539
540static void expectValidJniEnvAndClass(JNIEnv* env, jclass kls) {
541 if (!IsCurrentJniCritical()) {
542 EXPECT_EQ(Thread::Current()->GetJniEnv(), env);
543 ASSERT_TRUE(kls != nullptr);
544 EXPECT_TRUE(env->IsSameObject(static_cast<jobject>(JniCompilerTest::jklass_),
545 static_cast<jobject>(kls)));
546 } else {
547 // This is pretty much vacuously true but catch any testing setup mistakes.
Vladimir Markoc2208272020-07-23 11:04:39 +0000548 EXPECT_EQ(env, kCriticalFakeJniEnv);
549 EXPECT_EQ(kls, kCriticalFakeJniClass);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700550 }
551}
552
553// Validates the JNIEnv is the same as the current thread's JNIenv, and makes sure
554// that the jclass we got in the JNI handler is the same one as the class the method was looked
555// up for.
556//
Vladimir Markoc2208272020-07-23 11:04:39 +0000557// (Checks are skipped for @CriticalNative since the two values are fake).
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700558#define EXPECT_JNI_ENV_AND_CLASS_FOR_CURRENT_JNI(env, kls) expectValidJniEnvAndClass(env, kls)
559
560// Temporarily disable the EXPECT_NUM_STACK_REFERENCES check (for a single test).
561struct ScopedDisableCheckNumStackReferences {
562 ScopedDisableCheckNumStackReferences() {
Igor Murashkin06a04e02016-09-13 15:57:37 -0700563 CHECK(sCheckNumStackReferences); // No nested support.
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700564 sCheckNumStackReferences = false;
565 }
566
567 ~ScopedDisableCheckNumStackReferences() {
568 sCheckNumStackReferences = true;
569 }
570
571 static bool sCheckNumStackReferences;
572};
573
574bool ScopedDisableCheckNumStackReferences::sCheckNumStackReferences = true;
575
Roland Levillain2ae376f2018-01-30 11:35:11 +0000576// Check that the handle scope at the start of this block is the same
577// as the handle scope at the end of the block.
Igor Murashkina51d8b72016-10-05 14:33:30 -0700578struct ScopedCheckHandleScope {
Igor Murashkin42298112016-10-06 10:51:11 -0700579 ScopedCheckHandleScope() : handle_scope_(Thread::Current()->GetTopHandleScope()) {
Igor Murashkina51d8b72016-10-05 14:33:30 -0700580 }
581
582 ~ScopedCheckHandleScope() {
583 EXPECT_EQ(handle_scope_, Thread::Current()->GetTopHandleScope())
584 << "Top-most handle scope must be the same after all the JNI "
585 << "invocations have finished (as before they were invoked).";
586 }
587
Mathieu Chartiere8a3c572016-10-11 16:52:17 -0700588 BaseHandleScope* const handle_scope_;
Igor Murashkina51d8b72016-10-05 14:33:30 -0700589};
590
Vladimir Markocedec9d2021-02-08 16:16:13 +0000591class CountReferencesVisitor : public RootVisitor {
592 public:
Stefano Cianciulli78f3c722023-05-16 10:32:54 +0000593 void VisitRoots([[maybe_unused]] mirror::Object*** roots,
Vladimir Markocedec9d2021-02-08 16:16:13 +0000594 size_t count,
Stefano Cianciulli78f3c722023-05-16 10:32:54 +0000595 const RootInfo& info) override REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Markocedec9d2021-02-08 16:16:13 +0000596 if (info.GetType() == art::RootType::kRootJavaFrame) {
597 const JavaFrameRootInfo& jrfi = static_cast<const JavaFrameRootInfo&>(info);
598 if (jrfi.GetVReg() == JavaFrameRootInfo::kNativeReferenceArgument) {
599 DCHECK_EQ(count, 1u);
600 num_references_ += count;
601 }
602 }
Andreas Gampe0a855762016-10-26 13:43:14 -0700603 }
Vladimir Markocedec9d2021-02-08 16:16:13 +0000604
Stefano Cianciulli78f3c722023-05-16 10:32:54 +0000605 void VisitRoots([[maybe_unused]] mirror::CompressedReference<mirror::Object>** roots,
606 [[maybe_unused]] size_t count,
607 const RootInfo& info) override REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Markocedec9d2021-02-08 16:16:13 +0000608 CHECK_NE(info.GetType(), art::RootType::kRootJavaFrame);
609 }
610
611 size_t NumReferences() const {
612 return num_references_;
613 }
614
615 private:
616 size_t num_references_ = 0u;
617};
Andreas Gampe0a855762016-10-26 13:43:14 -0700618
619// Number of references allocated in handle scopes & JNI shadow frames on this thread.
620static size_t NumStackReferences(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Markocedec9d2021-02-08 16:16:13 +0000621 CountReferencesVisitor visitor;
622 self->VisitRoots(&visitor, kVisitRootFlagAllRoots);
623 return visitor.NumReferences();
Andreas Gampe0a855762016-10-26 13:43:14 -0700624}
625
Vladimir Markocedec9d2021-02-08 16:16:13 +0000626static void expectNumStackReferences(size_t expected) {
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700627 // In rare cases when JNI functions call themselves recursively,
628 // disable this test because it will have a false negative.
629 if (!IsCurrentJniCritical() && ScopedDisableCheckNumStackReferences::sCheckNumStackReferences) {
630 /* @CriticalNative doesn't build a HandleScope, so this test is meaningless then. */
631 ScopedObjectAccess soa(Thread::Current());
632
Vladimir Markocedec9d2021-02-08 16:16:13 +0000633 size_t num_references = NumStackReferences(Thread::Current());
634 EXPECT_EQ(expected, num_references);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700635 }
636}
637
Vladimir Markocedec9d2021-02-08 16:16:13 +0000638#define EXPECT_NUM_STACK_REFERENCES(expected) expectNumStackReferences(expected)
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700639
Yabin Cui948f0622020-02-04 17:18:41 -0800640template <typename T, T* fn>
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700641struct make_jni_test_decorator;
642
643// Decorator for "static" JNI callbacks.
Yabin Cui948f0622020-02-04 17:18:41 -0800644template <typename R, typename ... Args, R (*fn)(JNIEnv*, jclass, Args...)>
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700645struct make_jni_test_decorator<R(JNIEnv*, jclass kls, Args...), fn> {
646 static R apply(JNIEnv* env, jclass kls, Args ... args) {
647 EXPECT_THREAD_STATE_FOR_CURRENT_JNI();
648 EXPECT_MUTATOR_LOCK_FOR_CURRENT_JNI();
649 EXPECT_JNI_ENV_AND_CLASS_FOR_CURRENT_JNI(env, kls);
Vladimir Markocedec9d2021-02-08 16:16:13 +0000650 // All incoming parameters get spilled into the JNI transition frame.
651 // The `jclass` is just a reference to the method's declaring class field.
652 EXPECT_NUM_STACK_REFERENCES(count_nonnull_refs(args...));
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700653
654 return fn(env, kls, args...);
655 }
656};
657
658// Decorator for instance JNI callbacks.
Yabin Cui948f0622020-02-04 17:18:41 -0800659template <typename R, typename ... Args, R (*fn)(JNIEnv*, jobject, Args...)>
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700660struct make_jni_test_decorator<R(JNIEnv*, jobject, Args...), fn> {
661 static R apply(JNIEnv* env, jobject thisObj, Args ... args) {
662 EXPECT_THREAD_STATE_FOR_CURRENT_JNI();
663 EXPECT_MUTATOR_LOCK_FOR_CURRENT_JNI();
664 EXPECT_JNI_ENV_AND_OBJECT_FOR_CURRENT_JNI(env, thisObj);
Vladimir Markocedec9d2021-02-08 16:16:13 +0000665 // All incoming parameters + the implicit 'this' get spilled into the JNI transition frame.
666 EXPECT_NUM_STACK_REFERENCES(count_nonnull_refs(thisObj, args...));
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700667
668 return fn(env, thisObj, args...);
669 }
670};
671
672// Decorate the regular JNI callee with the extra gtest checks.
673// This way we can have common test logic for everything generic like checking if a lock is held,
674// checking handle scope state, etc.
675#define MAKE_JNI_TEST_DECORATOR(fn) make_jni_test_decorator<decltype(fn), (fn)>::apply
676
677// Convert function f(JNIEnv*,jclass,a,b,c,d...) into f2(a,b,c,d...)
678// -- This way we don't have to write out each implementation twice for @CriticalNative.
679#define JNI_CRITICAL_WRAPPER(func) jni_remove_extra_parameters<decltype(func), (func)>::apply
680// Get a function pointer whose calling convention either matches a regular native
681// or a critical native depending on which kind of jni is currently under test.
682// -- This also has the benefit of genering a compile time error if the 'func' doesn't properly
683// have JNIEnv and jclass parameters first.
684#define CURRENT_JNI_WRAPPER(func) \
685 (IsCurrentJniCritical() \
686 ? reinterpret_cast<void*>(&JNI_CRITICAL_WRAPPER(MAKE_JNI_TEST_DECORATOR(func))) \
687 : reinterpret_cast<void*>(&MAKE_JNI_TEST_DECORATOR(func)))
688
689// Do the opposite of the above. Do *not* wrap the function, instead just cast it to a void*.
690// Only for "TEST_JNI_NORMAL_ONLY" configs, and it inserts a test assert to ensure this is the case.
691#define NORMAL_JNI_ONLY_NOWRAP(func) \
692 ({ ASSERT_TRUE(IsCurrentJniNormal()); reinterpret_cast<void*>(&(func)); })
693// Same as above, but with nullptr. When we want to test the stub functionality.
Vladimir Markofa458ac2020-02-12 14:08:07 +0000694#define NORMAL_OR_FAST_JNI_ONLY_NULLPTR \
695 ({ ASSERT_TRUE(IsCurrentJniNormal() || IsCurrentJniFast()); nullptr; })
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700696
697
698int gJava_MyClassNatives_foo_calls[kJniKindCount] = {};
699void Java_MyClassNatives_foo(JNIEnv*, jobject) {
700 gJava_MyClassNatives_foo_calls[gCurrentJni]++;
Ian Rogersb033c752011-07-20 12:22:35 -0700701}
702
Andreas Gampe6e498692014-08-18 16:43:12 -0700703void JniCompilerTest::CompileAndRunNoArgMethodImpl() {
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700704 SetUpForTest(false, "foo", "()V", CURRENT_JNI_WRAPPER(Java_MyClassNatives_foo));
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700705
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700706 EXPECT_EQ(0, gJava_MyClassNatives_foo_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700707 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700708 EXPECT_EQ(1, gJava_MyClassNatives_foo_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700709 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700710 EXPECT_EQ(2, gJava_MyClassNatives_foo_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -0700711
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700712 gJava_MyClassNatives_foo_calls[gCurrentJni] = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700713}
714
Andreas Gampe6e498692014-08-18 16:43:12 -0700715JNI_TEST(CompileAndRunNoArgMethod)
716
717void JniCompilerTest::CompileAndRunIntMethodThroughStubImpl() {
Vladimir Markofa458ac2020-02-12 14:08:07 +0000718 SetUpForTest(false, "bar", "(I)I", NORMAL_OR_FAST_JNI_ONLY_NULLPTR);
719 // calling through stub will link with &Java_MyClassNatives_bar{,_1Fast}
Shih-wei Liao31384c52011-09-06 15:27:45 -0700720
Shih-wei Liao31384c52011-09-06 15:27:45 -0700721 std::string reason;
Dmitriy Ivanovf5a30992015-11-11 14:18:55 -0800722 ASSERT_TRUE(Runtime::Current()->GetJavaVM()->
Nicolas Geoffray96259f12019-01-18 10:04:51 +0000723 LoadNativeLibrary(env_, "", class_loader_, nullptr, &reason))
Ian Rogers68d8b422014-07-17 11:09:10 -0700724 << reason;
Shih-wei Liao31384c52011-09-06 15:27:45 -0700725
726 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 24);
727 EXPECT_EQ(25, result);
728}
729
Vladimir Markofa458ac2020-02-12 14:08:07 +0000730// Note: @CriticalNative is only for static methods.
731JNI_TEST(CompileAndRunIntMethodThroughStub)
Andreas Gampe6e498692014-08-18 16:43:12 -0700732
733void JniCompilerTest::CompileAndRunStaticIntMethodThroughStubImpl() {
Vladimir Markofa458ac2020-02-12 14:08:07 +0000734 SetUpForTest(true, "sbar", "(I)I", nullptr);
735 // calling through stub will link with &Java_MyClassNatives_sbar{,_1Fast,_1Critical}
Ian Rogers1cefdbd2012-02-29 09:34:50 -0800736
737 std::string reason;
Dmitriy Ivanovf5a30992015-11-11 14:18:55 -0800738 ASSERT_TRUE(Runtime::Current()->GetJavaVM()->
Nicolas Geoffray96259f12019-01-18 10:04:51 +0000739 LoadNativeLibrary(env_, "", class_loader_, nullptr, &reason))
Ian Rogers68d8b422014-07-17 11:09:10 -0700740 << reason;
Ian Rogers1cefdbd2012-02-29 09:34:50 -0800741
742 jint result = env_->CallStaticIntMethod(jklass_, jmethod_, 42);
743 EXPECT_EQ(43, result);
744}
745
Vladimir Markofa458ac2020-02-12 14:08:07 +0000746JNI_TEST_CRITICAL(CompileAndRunStaticIntMethodThroughStub)
Andreas Gampe6e498692014-08-18 16:43:12 -0700747
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700748int gJava_MyClassNatives_fooI_calls[kJniKindCount] = {};
749jint Java_MyClassNatives_fooI(JNIEnv*, jobject, jint x) {
750 gJava_MyClassNatives_fooI_calls[gCurrentJni]++;
Ian Rogersb033c752011-07-20 12:22:35 -0700751 return x;
752}
753
Andreas Gampe6e498692014-08-18 16:43:12 -0700754void JniCompilerTest::CompileAndRunIntMethodImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700755 SetUpForTest(false, "fooI", "(I)I",
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700756 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fooI));
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700757
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700758 EXPECT_EQ(0, gJava_MyClassNatives_fooI_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700759 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 42);
760 EXPECT_EQ(42, result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700761 EXPECT_EQ(1, gJava_MyClassNatives_fooI_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700762 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 0xCAFED00D);
763 EXPECT_EQ(static_cast<jint>(0xCAFED00D), result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700764 EXPECT_EQ(2, gJava_MyClassNatives_fooI_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -0700765
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700766 gJava_MyClassNatives_fooI_calls[gCurrentJni] = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700767}
768
Andreas Gampe6e498692014-08-18 16:43:12 -0700769JNI_TEST(CompileAndRunIntMethod)
770
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700771int gJava_MyClassNatives_fooII_calls[kJniKindCount] = {};
772jint Java_MyClassNatives_fooII(JNIEnv*, jobject, jint x, jint y) {
773 gJava_MyClassNatives_fooII_calls[gCurrentJni]++;
Ian Rogersb033c752011-07-20 12:22:35 -0700774 return x - y; // non-commutative operator
775}
776
Andreas Gampe6e498692014-08-18 16:43:12 -0700777void JniCompilerTest::CompileAndRunIntIntMethodImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700778 SetUpForTest(false, "fooII", "(II)I",
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700779 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fooII));
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700780
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700781 EXPECT_EQ(0, gJava_MyClassNatives_fooII_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700782 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 99, 10);
783 EXPECT_EQ(99 - 10, result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700784 EXPECT_EQ(1, gJava_MyClassNatives_fooII_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700785 result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 0xCAFEBABE,
786 0xCAFED00D);
787 EXPECT_EQ(static_cast<jint>(0xCAFEBABE - 0xCAFED00D), result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700788 EXPECT_EQ(2, gJava_MyClassNatives_fooII_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -0700789
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700790 gJava_MyClassNatives_fooII_calls[gCurrentJni] = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700791}
792
Andreas Gampe6e498692014-08-18 16:43:12 -0700793JNI_TEST(CompileAndRunIntIntMethod)
794
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700795int gJava_MyClassNatives_fooJJ_calls[kJniKindCount] = {};
796jlong Java_MyClassNatives_fooJJ(JNIEnv*, jobject, jlong x, jlong y) {
797 gJava_MyClassNatives_fooJJ_calls[gCurrentJni]++;
Ian Rogers9b269d22011-09-04 14:06:05 -0700798 return x - y; // non-commutative operator
799}
800
Andreas Gampe6e498692014-08-18 16:43:12 -0700801void JniCompilerTest::CompileAndRunLongLongMethodImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700802 SetUpForTest(false, "fooJJ", "(JJ)J",
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700803 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fooJJ));
Ian Rogers9b269d22011-09-04 14:06:05 -0700804
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700805 EXPECT_EQ(0, gJava_MyClassNatives_fooJJ_calls[gCurrentJni]);
Ian Rogers0f678472014-03-10 16:18:37 -0700806 jlong a = INT64_C(0x1234567890ABCDEF);
807 jlong b = INT64_C(0xFEDCBA0987654321);
Ian Rogers9b269d22011-09-04 14:06:05 -0700808 jlong result = env_->CallNonvirtualLongMethod(jobj_, jklass_, jmethod_, a, b);
809 EXPECT_EQ(a - b, result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700810 EXPECT_EQ(1, gJava_MyClassNatives_fooJJ_calls[gCurrentJni]);
Ian Rogers9b269d22011-09-04 14:06:05 -0700811 result = env_->CallNonvirtualLongMethod(jobj_, jklass_, jmethod_, b, a);
812 EXPECT_EQ(b - a, result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700813 EXPECT_EQ(2, gJava_MyClassNatives_fooJJ_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -0700814
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700815 gJava_MyClassNatives_fooJJ_calls[gCurrentJni] = 0;
Ian Rogers9b269d22011-09-04 14:06:05 -0700816}
817
Andreas Gampe6e498692014-08-18 16:43:12 -0700818JNI_TEST(CompileAndRunLongLongMethod)
819
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700820int gJava_MyClassNatives_fooDD_calls[kJniKindCount] = {};
821jdouble Java_MyClassNatives_fooDD(JNIEnv*, jobject, jdouble x, jdouble y) {
822 gJava_MyClassNatives_fooDD_calls[gCurrentJni]++;
Ian Rogersb033c752011-07-20 12:22:35 -0700823 return x - y; // non-commutative operator
824}
825
Andreas Gampe6e498692014-08-18 16:43:12 -0700826void JniCompilerTest::CompileAndRunDoubleDoubleMethodImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700827 SetUpForTest(false, "fooDD", "(DD)D",
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700828 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fooDD));
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700829
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700830 EXPECT_EQ(0, gJava_MyClassNatives_fooDD_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700831 jdouble result = env_->CallNonvirtualDoubleMethod(jobj_, jklass_, jmethod_,
832 99.0, 10.0);
Ian Rogers647b1a82014-10-10 11:02:11 -0700833 EXPECT_DOUBLE_EQ(99.0 - 10.0, result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700834 EXPECT_EQ(1, gJava_MyClassNatives_fooDD_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700835 jdouble a = 3.14159265358979323846;
836 jdouble b = 0.69314718055994530942;
837 result = env_->CallNonvirtualDoubleMethod(jobj_, jklass_, jmethod_, a, b);
Ian Rogers647b1a82014-10-10 11:02:11 -0700838 EXPECT_DOUBLE_EQ(a - b, result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700839 EXPECT_EQ(2, gJava_MyClassNatives_fooDD_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -0700840
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700841 gJava_MyClassNatives_fooDD_calls[gCurrentJni] = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700842}
843
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700844int gJava_MyClassNatives_fooJJ_synchronized_calls[kJniKindCount] = {};
Vladimir Markoce2a3442021-11-24 15:10:26 +0000845jlong Java_MyClassNatives_fooJJ_synchronized(JNIEnv* env, jobject, jlong x, jlong y) {
846 JniCompilerTest::AssertCallerObjectLocked(env);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700847 gJava_MyClassNatives_fooJJ_synchronized_calls[gCurrentJni]++;
Elliott Hughes3e778f72012-05-21 15:29:52 -0700848 return x | y;
849}
850
Vladimir Marko76e87952022-11-16 09:04:28 +0000851EXPORT // Defined in `libart.so`.
Vladimir Marko2ab607a2021-12-09 19:19:37 +0000852void InitEntryPoints(JniEntryPoints* jpoints,
853 QuickEntryPoints* qpoints,
854 bool monitor_jni_entry_exit);
855
Andreas Gampe6e498692014-08-18 16:43:12 -0700856void JniCompilerTest::CompileAndRun_fooJJ_synchronizedImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700857 SetUpForTest(false, "fooJJ_synchronized", "(JJ)J",
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700858 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fooJJ_synchronized));
Elliott Hughes3e778f72012-05-21 15:29:52 -0700859
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700860 EXPECT_EQ(0, gJava_MyClassNatives_fooJJ_synchronized_calls[gCurrentJni]);
Elliott Hughes3e778f72012-05-21 15:29:52 -0700861 jlong a = 0x1000000020000000ULL;
862 jlong b = 0x00ff000000aa0000ULL;
863 jlong result = env_->CallNonvirtualLongMethod(jobj_, jklass_, jmethod_, a, b);
864 EXPECT_EQ(a | b, result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700865 EXPECT_EQ(1, gJava_MyClassNatives_fooJJ_synchronized_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -0700866
Vladimir Marko3a50f342021-12-03 15:55:26 +0000867 // Exercise recursive thin locking/unlocking.
868 // Note: Thin lock count 0 means locked once.
869 env_->MonitorEnter(jobj_);
870 LockWord lock_word = GetLockWord(jobj_);
871 ASSERT_EQ(lock_word.GetState(), LockWord::kThinLocked);
872 ASSERT_EQ(lock_word.ThinLockCount(), 0u);
873 result = env_->CallNonvirtualLongMethod(jobj_, jklass_, jmethod_, a, b);
874 EXPECT_EQ(a | b, result);
875 EXPECT_EQ(2, gJava_MyClassNatives_fooJJ_synchronized_calls[gCurrentJni]);
876 lock_word = GetLockWord(jobj_);
877 ASSERT_EQ(lock_word.GetState(), LockWord::kThinLocked);
878 ASSERT_EQ(lock_word.ThinLockCount(), 0u);
879 env_->MonitorExit(jobj_);
880 lock_word = GetLockWord(jobj_);
881 ASSERT_EQ(lock_word.GetState(), LockWord::kUnlocked);
882
883 // Exercise lock inflation due to thin lock count overflow.
884 constexpr uint32_t kMaxThinLockRecursiveLocks = 1u << LockWord::kThinLockCountSize;
885 for (uint32_t i = 0; i != kMaxThinLockRecursiveLocks; ++i) {
886 env_->MonitorEnter(jobj_);
887 lock_word = GetLockWord(jobj_);
888 ASSERT_EQ(lock_word.GetState(), LockWord::kThinLocked);
889 ASSERT_EQ(lock_word.ThinLockCount(), i);
890 }
891 result = env_->CallNonvirtualLongMethod(jobj_, jklass_, jmethod_, a, b);
892 EXPECT_EQ(a | b, result);
893 EXPECT_EQ(3, gJava_MyClassNatives_fooJJ_synchronized_calls[gCurrentJni]);
894 lock_word = GetLockWord(jobj_);
895 ASSERT_EQ(lock_word.GetState(), LockWord::kFatLocked);
896 for (uint32_t i = 0; i != kMaxThinLockRecursiveLocks; ++i) {
897 env_->MonitorExit(jobj_); // Remains "fat-locked" even if actually unlocked.
898 }
899
900 // Exercise locking for "fat-locked".
901 lock_word = GetLockWord(jobj_);
902 ASSERT_EQ(lock_word.GetState(), LockWord::kFatLocked);
903 result = env_->CallNonvirtualLongMethod(jobj_, jklass_, jmethod_, a, b);
904 EXPECT_EQ(a | b, result);
905 EXPECT_EQ(4, gJava_MyClassNatives_fooJJ_synchronized_calls[gCurrentJni]);
906 lock_word = GetLockWord(jobj_);
907 ASSERT_EQ(lock_word.GetState(), LockWord::kFatLocked);
908
Vladimir Marko2ab607a2021-12-09 19:19:37 +0000909 // Exercise locking/unocking for "fat-locked" through the "no_inline" path.
910 // These entrypoints are selected with verbose "systrace_lock_logging".
911 Thread* self = Thread::Current();
912 ASSERT_FALSE(gLogVerbosity.systrace_lock_logging);
913 gLogVerbosity.systrace_lock_logging = true;
914 InitEntryPoints(&self->tlsPtr_.jni_entrypoints,
915 &self->tlsPtr_.quick_entrypoints,
916 self->ReadFlag(ThreadFlag::kMonitorJniEntryExit));
917 result = env_->CallNonvirtualLongMethod(jobj_, jklass_, jmethod_, a, b);
918 EXPECT_EQ(a | b, result);
919 EXPECT_EQ(5, gJava_MyClassNatives_fooJJ_synchronized_calls[gCurrentJni]);
920 gLogVerbosity.systrace_lock_logging = false;
921 InitEntryPoints(&self->tlsPtr_.jni_entrypoints,
922 &self->tlsPtr_.quick_entrypoints,
923 self->ReadFlag(ThreadFlag::kMonitorJniEntryExit));
924
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700925 gJava_MyClassNatives_fooJJ_synchronized_calls[gCurrentJni] = 0;
Elliott Hughes3e778f72012-05-21 15:29:52 -0700926}
927
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700928JNI_TEST_NORMAL_ONLY(CompileAndRun_fooJJ_synchronized)
Andreas Gampe6e498692014-08-18 16:43:12 -0700929
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700930int gJava_MyClassNatives_fooIOO_calls[kJniKindCount] = {};
931jobject Java_MyClassNatives_fooIOO(JNIEnv*, jobject thisObj, jint x, jobject y,
Ian Rogersb033c752011-07-20 12:22:35 -0700932 jobject z) {
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700933 gJava_MyClassNatives_fooIOO_calls[gCurrentJni]++;
Ian Rogersb033c752011-07-20 12:22:35 -0700934 switch (x) {
935 case 1:
936 return y;
937 case 2:
938 return z;
939 default:
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700940 return thisObj;
Ian Rogersb033c752011-07-20 12:22:35 -0700941 }
942}
943
Andreas Gampe6e498692014-08-18 16:43:12 -0700944void JniCompilerTest::CompileAndRunIntObjectObjectMethodImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700945 SetUpForTest(false, "fooIOO",
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700946 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700947 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fooIOO));
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700948
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700949 EXPECT_EQ(0, gJava_MyClassNatives_fooIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -0700950 jobject result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, nullptr, nullptr);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700951 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700952 EXPECT_EQ(1, gJava_MyClassNatives_fooIOO_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700953
Andreas Gampecf4035a2014-05-28 22:43:01 -0700954 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, nullptr, jklass_);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700955 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700956 EXPECT_EQ(2, gJava_MyClassNatives_fooIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -0700957 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 1, nullptr, jklass_);
958 EXPECT_TRUE(env_->IsSameObject(nullptr, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700959 EXPECT_EQ(3, gJava_MyClassNatives_fooIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -0700960 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 2, nullptr, jklass_);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700961 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700962 EXPECT_EQ(4, gJava_MyClassNatives_fooIOO_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700963
Andreas Gampecf4035a2014-05-28 22:43:01 -0700964 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 0, jklass_, nullptr);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700965 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700966 EXPECT_EQ(5, gJava_MyClassNatives_fooIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -0700967 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 1, jklass_, nullptr);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700968 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700969 EXPECT_EQ(6, gJava_MyClassNatives_fooIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -0700970 result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, 2, jklass_, nullptr);
971 EXPECT_TRUE(env_->IsSameObject(nullptr, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700972 EXPECT_EQ(7, gJava_MyClassNatives_fooIOO_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -0700973
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700974 gJava_MyClassNatives_fooIOO_calls[gCurrentJni] = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -0700975}
976
Igor Murashkinaf1e2992016-10-12 17:44:50 -0700977JNI_TEST(CompileAndRunIntObjectObjectMethod)
Andreas Gampe6e498692014-08-18 16:43:12 -0700978
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700979int gJava_MyClassNatives_fooSII_calls[kJniKindCount] = {};
Stefano Cianciulli78f3c722023-05-16 10:32:54 +0000980jint Java_MyClassNatives_fooSII([[maybe_unused]] JNIEnv* env,
981 [[maybe_unused]] jclass klass,
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700982 jint x,
983 jint y) {
984 gJava_MyClassNatives_fooSII_calls[gCurrentJni]++;
Shih-wei Liao82da44b2011-09-01 00:38:04 -0700985 return x + y;
986}
987
Andreas Gampe6e498692014-08-18 16:43:12 -0700988void JniCompilerTest::CompileAndRunStaticIntIntMethodImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700989 SetUpForTest(true, "fooSII", "(II)I",
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700990 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fooSII));
Shih-wei Liao82da44b2011-09-01 00:38:04 -0700991
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700992 EXPECT_EQ(0, gJava_MyClassNatives_fooSII_calls[gCurrentJni]);
Shih-wei Liao82da44b2011-09-01 00:38:04 -0700993 jint result = env_->CallStaticIntMethod(jklass_, jmethod_, 20, 30);
994 EXPECT_EQ(50, result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700995 EXPECT_EQ(1, gJava_MyClassNatives_fooSII_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -0700996
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700997 gJava_MyClassNatives_fooSII_calls[gCurrentJni] = 0;
Shih-wei Liao82da44b2011-09-01 00:38:04 -0700998}
999
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001000JNI_TEST_CRITICAL(CompileAndRunStaticIntIntMethod)
Andreas Gampe6e498692014-08-18 16:43:12 -07001001
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001002int gJava_MyClassNatives_fooSDD_calls[kJniKindCount] = {};
Stefano Cianciulli78f3c722023-05-16 10:32:54 +00001003jdouble Java_MyClassNatives_fooSDD([[maybe_unused]] JNIEnv* env,
1004 [[maybe_unused]] jclass klass,
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001005 jdouble x,
1006 jdouble y) {
1007 gJava_MyClassNatives_fooSDD_calls[gCurrentJni]++;
Ian Rogers7a99c112011-09-07 12:48:27 -07001008 return x - y; // non-commutative operator
1009}
1010
Andreas Gampe6e498692014-08-18 16:43:12 -07001011void JniCompilerTest::CompileAndRunStaticDoubleDoubleMethodImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001012 SetUpForTest(true, "fooSDD", "(DD)D",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001013 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fooSDD));
Ian Rogers7a99c112011-09-07 12:48:27 -07001014
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001015 EXPECT_EQ(0, gJava_MyClassNatives_fooSDD_calls[gCurrentJni]);
Ian Rogers7a99c112011-09-07 12:48:27 -07001016 jdouble result = env_->CallStaticDoubleMethod(jklass_, jmethod_, 99.0, 10.0);
Ian Rogers647b1a82014-10-10 11:02:11 -07001017 EXPECT_DOUBLE_EQ(99.0 - 10.0, result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001018 EXPECT_EQ(1, gJava_MyClassNatives_fooSDD_calls[gCurrentJni]);
Ian Rogers7a99c112011-09-07 12:48:27 -07001019 jdouble a = 3.14159265358979323846;
1020 jdouble b = 0.69314718055994530942;
1021 result = env_->CallStaticDoubleMethod(jklass_, jmethod_, a, b);
Ian Rogers647b1a82014-10-10 11:02:11 -07001022 EXPECT_DOUBLE_EQ(a - b, result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001023 EXPECT_DOUBLE_EQ(2, gJava_MyClassNatives_fooSDD_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -07001024
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001025 gJava_MyClassNatives_fooSDD_calls[gCurrentJni] = 0;
Ian Rogers7a99c112011-09-07 12:48:27 -07001026}
1027
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001028JNI_TEST_CRITICAL(CompileAndRunStaticDoubleDoubleMethod)
Andreas Gampe6e498692014-08-18 16:43:12 -07001029
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001030// The x86 generic JNI code had a bug where it assumed a floating
1031// point return value would be in xmm0. We use log, to somehow ensure
1032// the compiler will use the floating point stack.
1033
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001034jdouble Java_MyClassNatives_logD(JNIEnv*, jclass, jdouble x) {
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001035 return log(x);
1036}
1037
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001038jdouble Java_MyClassNatives_logD_notNormal(JNIEnv*, jclass, jdouble x) {
1039 EXPECT_DOUBLE_EQ(2.0, x);
1040 return log(x);
1041}
1042
Andreas Gampe6e498692014-08-18 16:43:12 -07001043void JniCompilerTest::RunStaticLogDoubleMethodImpl() {
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001044 void* jni_handler;
1045 if (IsCurrentJniNormal()) {
1046 // This test seems a bit special, don't use a JNI wrapper here.
1047 jni_handler = NORMAL_JNI_ONLY_NOWRAP(Java_MyClassNatives_logD);
1048 } else {
1049 jni_handler = CURRENT_JNI_WRAPPER(Java_MyClassNatives_logD_notNormal);
1050 }
1051 SetUpForTest(true, "logD", "(D)D", jni_handler);
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001052
1053 jdouble result = env_->CallStaticDoubleMethod(jklass_, jmethod_, 2.0);
Ian Rogers647b1a82014-10-10 11:02:11 -07001054 EXPECT_DOUBLE_EQ(log(2.0), result);
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001055}
1056
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001057JNI_TEST_CRITICAL(RunStaticLogDoubleMethod)
Andreas Gampe6e498692014-08-18 16:43:12 -07001058
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001059jfloat Java_MyClassNatives_logF(JNIEnv*, jclass, jfloat x) {
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001060 return logf(x);
1061}
1062
Andreas Gampe6e498692014-08-18 16:43:12 -07001063void JniCompilerTest::RunStaticLogFloatMethodImpl() {
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001064 void* jni_handler;
1065 if (IsCurrentJniNormal()) {
1066 // This test seems a bit special, don't use a JNI wrapper here.
1067 jni_handler = NORMAL_JNI_ONLY_NOWRAP(Java_MyClassNatives_logF);
1068 } else {
1069 jni_handler = CURRENT_JNI_WRAPPER(Java_MyClassNatives_logF);
1070 }
1071
1072 SetUpForTest(true, "logF", "(F)F", jni_handler);
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001073
1074 jfloat result = env_->CallStaticFloatMethod(jklass_, jmethod_, 2.0);
Ian Rogers647b1a82014-10-10 11:02:11 -07001075 EXPECT_FLOAT_EQ(logf(2.0), result);
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001076}
1077
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001078JNI_TEST_CRITICAL(RunStaticLogFloatMethod)
Andreas Gampe6e498692014-08-18 16:43:12 -07001079
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001080jboolean Java_MyClassNatives_returnTrue(JNIEnv*, jclass) {
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001081 return JNI_TRUE;
1082}
1083
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001084jboolean Java_MyClassNatives_returnFalse(JNIEnv*, jclass) {
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001085 return JNI_FALSE;
1086}
1087
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07001088jint Java_MyClassNatives_returnInt(JNIEnv*, jclass) {
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001089 return 42;
1090}
1091
Andreas Gampe6e498692014-08-18 16:43:12 -07001092void JniCompilerTest::RunStaticReturnTrueImpl() {
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001093 SetUpForTest(true, "returnTrue", "()Z", CURRENT_JNI_WRAPPER(Java_MyClassNatives_returnTrue));
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001094
1095 jboolean result = env_->CallStaticBooleanMethod(jklass_, jmethod_);
1096 EXPECT_TRUE(result);
1097}
1098
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001099JNI_TEST_CRITICAL(RunStaticReturnTrue)
Andreas Gampe6e498692014-08-18 16:43:12 -07001100
1101void JniCompilerTest::RunStaticReturnFalseImpl() {
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001102 SetUpForTest(true, "returnFalse", "()Z",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001103 CURRENT_JNI_WRAPPER(Java_MyClassNatives_returnFalse));
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001104
1105 jboolean result = env_->CallStaticBooleanMethod(jklass_, jmethod_);
1106 EXPECT_FALSE(result);
1107}
1108
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001109JNI_TEST_CRITICAL(RunStaticReturnFalse)
Andreas Gampe6e498692014-08-18 16:43:12 -07001110
1111void JniCompilerTest::RunGenericStaticReturnIntImpl() {
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001112 SetUpForTest(true, "returnInt", "()I", CURRENT_JNI_WRAPPER(Java_MyClassNatives_returnInt));
Nicolas Geoffray54accbc2014-08-13 03:40:45 +01001113
1114 jint result = env_->CallStaticIntMethod(jklass_, jmethod_);
1115 EXPECT_EQ(42, result);
1116}
1117
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001118JNI_TEST_CRITICAL(RunGenericStaticReturnInt)
Andreas Gampe6e498692014-08-18 16:43:12 -07001119
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001120int gJava_MyClassNatives_returnDouble_calls[kJniKindCount] = {};
1121jdouble Java_MyClassNatives_returnDouble(JNIEnv*, jclass) {
1122 gJava_MyClassNatives_returnDouble_calls[gCurrentJni]++;
1123 return 4.0;
1124}
1125
1126void JniCompilerTest::RunGenericStaticReturnDoubleImpl() {
1127 SetUpForTest(true, "returnDouble", "()D", CURRENT_JNI_WRAPPER(Java_MyClassNatives_returnDouble));
1128
1129 jdouble result = env_->CallStaticDoubleMethod(jklass_, jmethod_);
1130 EXPECT_DOUBLE_EQ(4.0, result);
1131 EXPECT_EQ(1, gJava_MyClassNatives_returnDouble_calls[gCurrentJni]);
1132
1133 gJava_MyClassNatives_returnDouble_calls[gCurrentJni] = 0;
1134}
1135
1136JNI_TEST_CRITICAL(RunGenericStaticReturnDouble)
1137
1138jlong Java_MyClassNatives_returnLong(JNIEnv*, jclass) {
1139 return 0xFEEDDEADFEEDL;
1140}
1141
1142void JniCompilerTest::RunGenericStaticReturnLongImpl() {
1143 SetUpForTest(true, "returnLong", "()J", CURRENT_JNI_WRAPPER(Java_MyClassNatives_returnLong));
1144
1145 jlong result = env_->CallStaticLongMethod(jklass_, jmethod_);
1146 EXPECT_EQ(0xFEEDDEADFEEDL, result);
1147}
1148
1149JNI_TEST_CRITICAL(RunGenericStaticReturnLong)
1150
1151int gJava_MyClassNatives_fooSIOO_calls[kJniKindCount] = {};
1152jobject Java_MyClassNatives_fooSIOO(JNIEnv*, jclass klass, jint x, jobject y, jobject z) {
1153 gJava_MyClassNatives_fooSIOO_calls[gCurrentJni]++;
Ian Rogersb033c752011-07-20 12:22:35 -07001154 switch (x) {
1155 case 1:
1156 return y;
1157 case 2:
1158 return z;
1159 default:
1160 return klass;
1161 }
1162}
1163
Andreas Gampe6e498692014-08-18 16:43:12 -07001164void JniCompilerTest::CompileAndRunStaticIntObjectObjectMethodImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001165 SetUpForTest(true, "fooSIOO",
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001166 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001167 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fooSIOO));
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001168
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001169 EXPECT_EQ(0, gJava_MyClassNatives_fooSIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001170 jobject result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, nullptr, nullptr);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001171 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001172 EXPECT_EQ(1, gJava_MyClassNatives_fooSIOO_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001173
Andreas Gampecf4035a2014-05-28 22:43:01 -07001174 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, nullptr, jobj_);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001175 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001176 EXPECT_EQ(2, gJava_MyClassNatives_fooSIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001177 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, nullptr, jobj_);
1178 EXPECT_TRUE(env_->IsSameObject(nullptr, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001179 EXPECT_EQ(3, gJava_MyClassNatives_fooSIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001180 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, nullptr, jobj_);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001181 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001182 EXPECT_EQ(4, gJava_MyClassNatives_fooSIOO_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001183
Andreas Gampecf4035a2014-05-28 22:43:01 -07001184 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, jobj_, nullptr);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001185 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001186 EXPECT_EQ(5, gJava_MyClassNatives_fooSIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001187 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, jobj_, nullptr);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001188 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001189 EXPECT_EQ(6, gJava_MyClassNatives_fooSIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001190 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, jobj_, nullptr);
1191 EXPECT_TRUE(env_->IsSameObject(nullptr, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001192 EXPECT_EQ(7, gJava_MyClassNatives_fooSIOO_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -07001193
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001194 gJava_MyClassNatives_fooSIOO_calls[gCurrentJni] = 0;
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001195}
1196
Igor Murashkinaf1e2992016-10-12 17:44:50 -07001197JNI_TEST(CompileAndRunStaticIntObjectObjectMethod)
Andreas Gampe6e498692014-08-18 16:43:12 -07001198
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001199int gJava_MyClassNatives_fooSSIOO_calls[kJniKindCount] = {};
Vladimir Markoce2a3442021-11-24 15:10:26 +00001200jobject Java_MyClassNatives_fooSSIOO(JNIEnv* env, jclass klass, jint x, jobject y, jobject z) {
1201 JniCompilerTest::AssertCallerObjectLocked(env);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001202 gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]++;
Ian Rogersdf20fe02011-07-20 20:34:16 -07001203 switch (x) {
1204 case 1:
1205 return y;
1206 case 2:
1207 return z;
1208 default:
1209 return klass;
1210 }
1211}
1212
Andreas Gampe6e498692014-08-18 16:43:12 -07001213void JniCompilerTest::CompileAndRunStaticSynchronizedIntObjectObjectMethodImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001214 SetUpForTest(true, "fooSSIOO",
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001215 "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001216 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fooSSIOO));
Carl Shapiro419ec7b2011-08-03 14:48:33 -07001217
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001218 EXPECT_EQ(0, gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001219 jobject result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, nullptr, nullptr);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001220 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001221 EXPECT_EQ(1, gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001222
Andreas Gampecf4035a2014-05-28 22:43:01 -07001223 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, nullptr, jobj_);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001224 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001225 EXPECT_EQ(2, gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001226 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, nullptr, jobj_);
1227 EXPECT_TRUE(env_->IsSameObject(nullptr, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001228 EXPECT_EQ(3, gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001229 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, nullptr, jobj_);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001230 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001231 EXPECT_EQ(4, gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001232
Andreas Gampecf4035a2014-05-28 22:43:01 -07001233 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 0, jobj_, nullptr);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001234 EXPECT_TRUE(env_->IsSameObject(jklass_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001235 EXPECT_EQ(5, gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001236 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 1, jobj_, nullptr);
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001237 EXPECT_TRUE(env_->IsSameObject(jobj_, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001238 EXPECT_EQ(6, gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001239 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, jobj_, nullptr);
1240 EXPECT_TRUE(env_->IsSameObject(nullptr, result));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001241 EXPECT_EQ(7, gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -07001242
Vladimir Marko3a50f342021-12-03 15:55:26 +00001243 // Exercise recursive thin locking/unlocking.
1244 // Note: Thin lock count 0 means locked once.
1245 env_->MonitorEnter(jklass_);
1246 LockWord lock_word = GetLockWord(jklass_);
1247 ASSERT_EQ(lock_word.GetState(), LockWord::kThinLocked);
1248 ASSERT_EQ(lock_word.ThinLockCount(), 0u);
1249 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, jobj_, nullptr);
1250 EXPECT_TRUE(env_->IsSameObject(nullptr, result));
1251 EXPECT_EQ(8, gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]);
1252 lock_word = GetLockWord(jklass_);
1253 ASSERT_EQ(lock_word.GetState(), LockWord::kThinLocked);
1254 ASSERT_EQ(lock_word.ThinLockCount(), 0u);
1255 env_->MonitorExit(jklass_);
1256 lock_word = GetLockWord(jklass_);
1257 ASSERT_EQ(lock_word.GetState(), LockWord::kUnlocked);
1258
1259 // Exercise lock inflation due to thin lock count overflow.
1260 constexpr uint32_t kMaxThinLockRecursiveLocks = 1u << LockWord::kThinLockCountSize;
1261 for (uint32_t i = 0; i != kMaxThinLockRecursiveLocks; ++i) {
1262 env_->MonitorEnter(jklass_);
1263 lock_word = GetLockWord(jklass_);
1264 ASSERT_EQ(lock_word.GetState(), LockWord::kThinLocked);
1265 ASSERT_EQ(lock_word.ThinLockCount(), i);
1266 }
1267 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, jobj_, nullptr);
1268 EXPECT_TRUE(env_->IsSameObject(nullptr, result));
1269 EXPECT_EQ(9, gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]);
1270 lock_word = GetLockWord(jklass_);
1271 ASSERT_EQ(lock_word.GetState(), LockWord::kFatLocked);
1272 for (uint32_t i = 0; i != kMaxThinLockRecursiveLocks; ++i) {
1273 env_->MonitorExit(jklass_); // Remains "fat-locked" even if actually unlocked.
1274 }
1275
1276 // Exercise locking for "fat-locked".
1277 lock_word = GetLockWord(jklass_);
1278 result = env_->CallStaticObjectMethod(jklass_, jmethod_, 2, jobj_, nullptr);
1279 EXPECT_TRUE(env_->IsSameObject(nullptr, result));
1280 EXPECT_EQ(10, gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni]);
1281 lock_word = GetLockWord(jklass_);
1282 ASSERT_EQ(lock_word.GetState(), LockWord::kFatLocked);
1283
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001284 gJava_MyClassNatives_fooSSIOO_calls[gCurrentJni] = 0;
Ian Rogersdf20fe02011-07-20 20:34:16 -07001285}
1286
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001287// TODO: Maybe. @FastNative support for returning Objects?
1288JNI_TEST_NORMAL_ONLY(CompileAndRunStaticSynchronizedIntObjectObjectMethod)
Andreas Gampe6e498692014-08-18 16:43:12 -07001289
Elliott Hughesb264f082012-04-06 17:10:10 -07001290void Java_MyClassNatives_throwException(JNIEnv* env, jobject) {
Elliott Hughesa2501992011-08-26 19:39:54 -07001291 jclass c = env->FindClass("java/lang/RuntimeException");
1292 env->ThrowNew(c, "hello");
1293}
Ian Rogers45a76cb2011-07-21 22:00:15 -07001294
Vladimir Marko2cdb3672021-12-08 12:19:00 +00001295void Java_MyClassNatives_synchronizedThrowException(JNIEnv* env, jobject) {
1296 JniCompilerTest::AssertCallerObjectLocked(env);
1297 jclass c = env->FindClass("java/lang/RuntimeException");
1298 env->ThrowNew(c, "hello");
1299}
1300
Andreas Gampe6e498692014-08-18 16:43:12 -07001301void JniCompilerTest::ExceptionHandlingImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001302 {
1303 ASSERT_FALSE(runtime_->IsStarted());
1304 ScopedObjectAccess soa(Thread::Current());
1305 class_loader_ = LoadDex("MyClassNatives");
Brian Carlstrom40381fb2011-10-19 14:13:40 -07001306
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001307 // all compilation needs to happen before Runtime::Start
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001308 CompileForTestWithCurrentJni(class_loader_, false, "foo", "()V");
1309 CompileForTestWithCurrentJni(class_loader_, false, "throwException", "()V");
Vladimir Marko2cdb3672021-12-08 12:19:00 +00001310 if (gCurrentJni == enum_cast<uint32_t>(JniKind::kNormal)) {
1311 CompileForTestWithCurrentJni(class_loader_, false, "synchronizedThrowException", "()V");
1312 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001313 }
Hans Boehmba5cc5b2022-09-09 22:43:53 +00001314 // Start runtime to avoid re-initialization in SetUpForTest.
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001315 Thread::Current()->TransitionFromSuspendedToRunnable();
Brian Carlstrombd86bcc2013-03-10 20:26:16 -07001316 bool started = runtime_->Start();
1317 CHECK(started);
Brian Carlstrom25c33252011-09-18 15:58:35 -07001318
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001319 gJava_MyClassNatives_foo_calls[gCurrentJni] = 0;
Elliott Hughesa2501992011-08-26 19:39:54 -07001320
Ian Rogers67375ac2011-09-14 00:55:44 -07001321 // Check a single call of a JNI method is ok
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001322 SetUpForTest(false, "foo", "()V", CURRENT_JNI_WRAPPER(Java_MyClassNatives_foo));
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001323 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001324 EXPECT_EQ(1, gJava_MyClassNatives_foo_calls[gCurrentJni]);
Ian Rogers67375ac2011-09-14 00:55:44 -07001325 EXPECT_FALSE(Thread::Current()->IsExceptionPending());
Elliott Hughesa2501992011-08-26 19:39:54 -07001326
Ian Rogers67375ac2011-09-14 00:55:44 -07001327 // Get class for exception we expect to be thrown
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001328 ScopedLocalRef<jclass> jlre(env_, env_->FindClass("java/lang/RuntimeException"));
1329 SetUpForTest(false, "throwException", "()V",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001330 CURRENT_JNI_WRAPPER(Java_MyClassNatives_throwException));
Elliott Hughesb264f082012-04-06 17:10:10 -07001331 // Call Java_MyClassNatives_throwException (JNI method that throws exception)
Elliott Hughesa2501992011-08-26 19:39:54 -07001332 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001333 EXPECT_TRUE(env_->ExceptionCheck() == JNI_TRUE);
1334 ScopedLocalRef<jthrowable> exception(env_, env_->ExceptionOccurred());
1335 env_->ExceptionClear();
1336 EXPECT_TRUE(env_->IsInstanceOf(exception.get(), jlre.get()));
Elliott Hughesa2501992011-08-26 19:39:54 -07001337
Ian Rogers67375ac2011-09-14 00:55:44 -07001338 // Check a single call of a JNI method is ok
Vladimir Marko2cdb3672021-12-08 12:19:00 +00001339 EXPECT_EQ(1, gJava_MyClassNatives_foo_calls[gCurrentJni]);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001340 SetUpForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClassNatives_foo));
Ian Rogerscdd1d2d2011-08-18 09:58:17 -07001341 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001342 EXPECT_EQ(2, gJava_MyClassNatives_foo_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -07001343
Vladimir Marko2cdb3672021-12-08 12:19:00 +00001344 if (gCurrentJni == enum_cast<uint32_t>(JniKind::kNormal)) {
1345 SetUpForTest(false, "synchronizedThrowException", "()V",
1346 CURRENT_JNI_WRAPPER(Java_MyClassNatives_synchronizedThrowException));
1347 LockWord lock_word = GetLockWord(jobj_);
1348 ASSERT_EQ(lock_word.GetState(), LockWord::kUnlocked);
1349 // Call Java_MyClassNatives_synchronizedThrowException (synchronized JNI method
1350 // that throws exception) to check that we correctly unlock the object.
1351 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
1352 EXPECT_TRUE(env_->ExceptionCheck() == JNI_TRUE);
1353 ScopedLocalRef<jthrowable> exception2(env_, env_->ExceptionOccurred());
1354 env_->ExceptionClear();
1355 EXPECT_TRUE(env_->IsInstanceOf(exception2.get(), jlre.get()));
1356 lock_word = GetLockWord(jobj_);
1357 EXPECT_EQ(lock_word.GetState(), LockWord::kUnlocked);
1358
1359 // Check a single call of a JNI method is ok
1360 EXPECT_EQ(2, gJava_MyClassNatives_foo_calls[gCurrentJni]);
1361 SetUpForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClassNatives_foo));
1362 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_);
1363 EXPECT_EQ(3, gJava_MyClassNatives_foo_calls[gCurrentJni]);
1364 }
1365
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001366 gJava_MyClassNatives_foo_calls[gCurrentJni] = 0;
Ian Rogers45a76cb2011-07-21 22:00:15 -07001367}
1368
Andreas Gampe6e498692014-08-18 16:43:12 -07001369JNI_TEST(ExceptionHandling)
1370
Elliott Hughesb264f082012-04-06 17:10:10 -07001371jint Java_MyClassNatives_nativeUpCall(JNIEnv* env, jobject thisObj, jint i) {
Shih-wei Liaoff0f9be2011-08-29 15:43:53 -07001372 if (i <= 0) {
Andreas Gampecf4035a2014-05-28 22:43:01 -07001373 // We want to check raw Object* / Array* below
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001374 ScopedObjectAccess soa(env);
Ian Rogersaaa20802011-09-11 21:47:37 -07001375
1376 // Build stack trace
Vladimir Markod34b73b2020-05-05 10:07:59 +01001377 jobject internal = Thread::Current()->CreateInternalStackTrace(soa);
Ian Rogers53b8b092014-03-13 23:45:53 -07001378 jobjectArray ste_array = Thread::InternalStackTraceToStackTraceElementArray(soa, internal);
Mathieu Chartier0795f232016-09-27 18:43:30 -07001379 ObjPtr<mirror::ObjectArray<mirror::StackTraceElement>> trace_array =
1380 soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>>(ste_array);
Andreas Gampecf4035a2014-05-28 22:43:01 -07001381 EXPECT_TRUE(trace_array != nullptr);
Shih-wei Liaoff0f9be2011-08-29 15:43:53 -07001382 EXPECT_EQ(11, trace_array->GetLength());
1383
Ian Rogersaaa20802011-09-11 21:47:37 -07001384 // Check stack trace entries have expected values
Andreas Gampe277ccbd2014-11-03 21:36:10 -08001385 for (int32_t j = 0; j < trace_array->GetLength(); ++j) {
1386 EXPECT_EQ(-2, trace_array->Get(j)->GetLineNumber());
Vladimir Marko423bebb2019-03-26 15:17:21 +00001387 ObjPtr<mirror::StackTraceElement> ste = trace_array->Get(j);
Ian Rogersaaa20802011-09-11 21:47:37 -07001388 EXPECT_STREQ("MyClassNatives.java", ste->GetFileName()->ToModifiedUtf8().c_str());
Elliott Hughesb264f082012-04-06 17:10:10 -07001389 EXPECT_STREQ("MyClassNatives", ste->GetDeclaringClass()->ToModifiedUtf8().c_str());
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001390 EXPECT_EQ(("fooI" + CurrentJniStringSuffix()), ste->GetMethodName()->ToModifiedUtf8());
Shih-wei Liaoff0f9be2011-08-29 15:43:53 -07001391 }
Ian Rogersaaa20802011-09-11 21:47:37 -07001392
1393 // end recursion
Shih-wei Liaoff0f9be2011-08-29 15:43:53 -07001394 return 0;
1395 } else {
Elliott Hughesb264f082012-04-06 17:10:10 -07001396 jclass jklass = env->FindClass("MyClassNatives");
Andreas Gampecf4035a2014-05-28 22:43:01 -07001397 EXPECT_TRUE(jklass != nullptr);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001398 jmethodID jmethod = env->GetMethodID(jklass,
1399 ("fooI" + CurrentJniStringSuffix()).c_str(),
1400 "(I)I");
Andreas Gampecf4035a2014-05-28 22:43:01 -07001401 EXPECT_TRUE(jmethod != nullptr);
Shih-wei Liaoff0f9be2011-08-29 15:43:53 -07001402
Ian Rogersaaa20802011-09-11 21:47:37 -07001403 // Recurse with i - 1
Shih-wei Liaoff0f9be2011-08-29 15:43:53 -07001404 jint result = env->CallNonvirtualIntMethod(thisObj, jklass, jmethod, i - 1);
Ian Rogersaaa20802011-09-11 21:47:37 -07001405
1406 // Return sum of all depths
Shih-wei Liaoff0f9be2011-08-29 15:43:53 -07001407 return i + result;
1408 }
1409}
1410
Andreas Gampe6e498692014-08-18 16:43:12 -07001411void JniCompilerTest::NativeStackTraceElementImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001412 SetUpForTest(false, "fooI", "(I)I",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001413 CURRENT_JNI_WRAPPER(Java_MyClassNatives_nativeUpCall));
1414
1415 // Usual # local references on stack check fails because nativeUpCall calls itself recursively,
1416 // each time the # of local references will therefore go up.
1417 ScopedDisableCheckNumStackReferences disable_num_stack_check;
Shih-wei Liaoff0f9be2011-08-29 15:43:53 -07001418 jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 10);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001419
Ian Rogersaaa20802011-09-11 21:47:37 -07001420 EXPECT_EQ(10+9+8+7+6+5+4+3+2+1, result);
Shih-wei Liaoff0f9be2011-08-29 15:43:53 -07001421}
1422
Andreas Gampe6e498692014-08-18 16:43:12 -07001423JNI_TEST(NativeStackTraceElement)
1424
Elliott Hughesb264f082012-04-06 17:10:10 -07001425jobject Java_MyClassNatives_fooO(JNIEnv* env, jobject, jobject x) {
Shih-wei Liao558788e2011-09-01 02:39:11 -07001426 return env->NewGlobalRef(x);
1427}
1428
Andreas Gampe6e498692014-08-18 16:43:12 -07001429void JniCompilerTest::ReturnGlobalRefImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001430 SetUpForTest(false, "fooO", "(Ljava/lang/Object;)Ljava/lang/Object;",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001431 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fooO));
Shih-wei Liao558788e2011-09-01 02:39:11 -07001432 jobject result = env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, jobj_);
1433 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(result));
1434 EXPECT_TRUE(env_->IsSameObject(result, jobj_));
1435}
1436
Igor Murashkinaf1e2992016-10-12 17:44:50 -07001437JNI_TEST(ReturnGlobalRef)
Andreas Gampe6e498692014-08-18 16:43:12 -07001438
Ian Rogersdc51b792011-09-22 20:41:37 -07001439jint local_ref_test(JNIEnv* env, jobject thisObj, jint x) {
1440 // Add 10 local references
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001441 ScopedObjectAccess soa(env);
Ian Rogers5a7a74a2011-09-26 16:32:29 -07001442 for (int i = 0; i < 10; i++) {
Mathieu Chartier0795f232016-09-27 18:43:30 -07001443 soa.AddLocalReference<jobject>(soa.Decode<mirror::Object>(thisObj));
Ian Rogersdc51b792011-09-22 20:41:37 -07001444 }
1445 return x+1;
1446}
1447
Andreas Gampe6e498692014-08-18 16:43:12 -07001448void JniCompilerTest::LocalReferenceTableClearingTestImpl() {
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001449 SetUpForTest(false, "fooI", "(I)I", CURRENT_JNI_WRAPPER(local_ref_test));
Ian Rogersdc51b792011-09-22 20:41:37 -07001450 // 1000 invocations of a method that adds 10 local references
Elliott Hughesb25c3f62012-03-26 16:35:06 -07001451 for (int i = 0; i < 1000; i++) {
Ian Rogersdc51b792011-09-22 20:41:37 -07001452 jint result = env_->CallIntMethod(jobj_, jmethod_, i);
1453 EXPECT_TRUE(result == i + 1);
1454 }
1455}
1456
Andreas Gampe6e498692014-08-18 16:43:12 -07001457JNI_TEST(LocalReferenceTableClearingTest)
1458
Ian Rogersb9231c82011-09-05 22:13:19 -07001459void my_arraycopy(JNIEnv* env, jclass klass, jobject src, jint src_pos, jobject dst, jint dst_pos, jint length) {
1460 EXPECT_TRUE(env->IsSameObject(JniCompilerTest::jklass_, klass));
1461 EXPECT_TRUE(env->IsSameObject(JniCompilerTest::jklass_, dst));
Ian Rogers82f3e092011-09-05 22:54:45 -07001462 EXPECT_TRUE(env->IsSameObject(JniCompilerTest::jobj_, src));
Ian Rogersb9231c82011-09-05 22:13:19 -07001463 EXPECT_EQ(1234, src_pos);
1464 EXPECT_EQ(5678, dst_pos);
1465 EXPECT_EQ(9876, length);
1466}
1467
Andreas Gampe6e498692014-08-18 16:43:12 -07001468void JniCompilerTest::JavaLangSystemArrayCopyImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001469 SetUpForTest(true, "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001470 CURRENT_JNI_WRAPPER(my_arraycopy));
Ian Rogers82f3e092011-09-05 22:54:45 -07001471 env_->CallStaticVoidMethod(jklass_, jmethod_, jobj_, 1234, jklass_, 5678, 9876);
Ian Rogersb9231c82011-09-05 22:13:19 -07001472}
1473
Andreas Gampe6e498692014-08-18 16:43:12 -07001474JNI_TEST(JavaLangSystemArrayCopy)
1475
Ian Rogers67375ac2011-09-14 00:55:44 -07001476jboolean my_casi(JNIEnv* env, jobject unsafe, jobject obj, jlong offset, jint expected, jint newval) {
1477 EXPECT_TRUE(env->IsSameObject(JniCompilerTest::jobj_, unsafe));
1478 EXPECT_TRUE(env->IsSameObject(JniCompilerTest::jobj_, obj));
Ian Rogers0f678472014-03-10 16:18:37 -07001479 EXPECT_EQ(INT64_C(0x12345678ABCDEF88), offset);
Ian Rogers67375ac2011-09-14 00:55:44 -07001480 EXPECT_EQ(static_cast<jint>(0xCAFEF00D), expected);
1481 EXPECT_EQ(static_cast<jint>(0xEBADF00D), newval);
1482 return JNI_TRUE;
1483}
1484
Andreas Gampe6e498692014-08-18 16:43:12 -07001485void JniCompilerTest::CompareAndSwapIntImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001486 SetUpForTest(false, "compareAndSwapInt", "(Ljava/lang/Object;JII)Z",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001487 CURRENT_JNI_WRAPPER(my_casi));
Ian Rogers0f678472014-03-10 16:18:37 -07001488 jboolean result = env_->CallBooleanMethod(jobj_, jmethod_, jobj_, INT64_C(0x12345678ABCDEF88),
1489 0xCAFEF00D, 0xEBADF00D);
Ian Rogers67375ac2011-09-14 00:55:44 -07001490 EXPECT_EQ(result, JNI_TRUE);
1491}
1492
Andreas Gampe6e498692014-08-18 16:43:12 -07001493JNI_TEST(CompareAndSwapInt)
1494
Ian Rogersc7792842012-03-03 15:36:20 -08001495jint my_gettext(JNIEnv* env, jclass klass, jlong val1, jobject obj1, jlong val2, jobject obj2) {
1496 EXPECT_TRUE(env->IsInstanceOf(JniCompilerTest::jobj_, klass));
1497 EXPECT_TRUE(env->IsSameObject(JniCompilerTest::jobj_, obj1));
1498 EXPECT_TRUE(env->IsSameObject(JniCompilerTest::jobj_, obj2));
Chih-Hung Hsieh457a0172018-12-10 13:08:27 -08001499 EXPECT_EQ(0x12345678ABCDEF88LL, val1);
1500 EXPECT_EQ(0x7FEDCBA987654321LL, val2);
Ian Rogersc7792842012-03-03 15:36:20 -08001501 return 42;
1502}
1503
Andreas Gampe6e498692014-08-18 16:43:12 -07001504void JniCompilerTest::GetTextImpl() {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001505 SetUpForTest(true, "getText", "(JLjava/lang/Object;JLjava/lang/Object;)I",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001506 CURRENT_JNI_WRAPPER(my_gettext));
Chih-Hung Hsieh457a0172018-12-10 13:08:27 -08001507 jint result = env_->CallStaticIntMethod(jklass_, jmethod_, 0x12345678ABCDEF88LL, jobj_,
Ian Rogers0f678472014-03-10 16:18:37 -07001508 INT64_C(0x7FEDCBA987654321), jobj_);
Ian Rogersc7792842012-03-03 15:36:20 -08001509 EXPECT_EQ(result, 42);
1510}
1511
Andreas Gampe6e498692014-08-18 16:43:12 -07001512JNI_TEST(GetText)
1513
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001514int gJava_MyClassNatives_GetSinkProperties_calls[kJniKindCount] = {};
Vladimir Markoce2a3442021-11-24 15:10:26 +00001515jarray Java_MyClassNatives_GetSinkProperties(JNIEnv* env, jobject thisObj, jstring s) {
1516 JniCompilerTest::AssertCallerObjectLocked(env);
Vladimir Marko4e24b9d2014-07-24 17:01:58 +01001517 EXPECT_EQ(s, nullptr);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001518 gJava_MyClassNatives_GetSinkProperties_calls[gCurrentJni]++;
1519
1520 Thread* self = Thread::Current();
Vladimir Marko4e24b9d2014-07-24 17:01:58 +01001521 ScopedObjectAccess soa(self);
Vladimir Marko179b7c62019-03-22 13:38:57 +00001522 EXPECT_TRUE(self->HoldsLock(soa.Decode<mirror::Object>(thisObj)));
Vladimir Marko4e24b9d2014-07-24 17:01:58 +01001523 return nullptr;
1524}
1525
Andreas Gampe6e498692014-08-18 16:43:12 -07001526void JniCompilerTest::GetSinkPropertiesNativeImpl() {
Vladimir Marko4e24b9d2014-07-24 17:01:58 +01001527 SetUpForTest(false, "getSinkPropertiesNative", "(Ljava/lang/String;)[Ljava/lang/Object;",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001528 CURRENT_JNI_WRAPPER(Java_MyClassNatives_GetSinkProperties));
Vladimir Marko4e24b9d2014-07-24 17:01:58 +01001529
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001530 EXPECT_EQ(0, gJava_MyClassNatives_GetSinkProperties_calls[gCurrentJni]);
Vladimir Marko4e24b9d2014-07-24 17:01:58 +01001531 jarray result = down_cast<jarray>(
1532 env_->CallNonvirtualObjectMethod(jobj_, jklass_, jmethod_, nullptr));
1533 EXPECT_EQ(nullptr, result);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001534 EXPECT_EQ(1, gJava_MyClassNatives_GetSinkProperties_calls[gCurrentJni]);
Andreas Gampe6e498692014-08-18 16:43:12 -07001535
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001536 gJava_MyClassNatives_GetSinkProperties_calls[gCurrentJni] = 0;
Brian Carlstromfc7120c2012-08-27 13:43:25 -07001537}
1538
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001539// @FastNative doesn't support 'synchronized' keyword and
1540// never will -- locking functions aren't fast.
1541JNI_TEST_NORMAL_ONLY(GetSinkPropertiesNative)
Andreas Gampe6e498692014-08-18 16:43:12 -07001542
Elliott Hughesb264f082012-04-06 17:10:10 -07001543// This should return jclass, but we're imitating a bug pattern.
1544jobject Java_MyClassNatives_instanceMethodThatShouldReturnClass(JNIEnv* env, jobject) {
1545 return env->NewStringUTF("not a class!");
1546}
1547
1548// This should return jclass, but we're imitating a bug pattern.
1549jobject Java_MyClassNatives_staticMethodThatShouldReturnClass(JNIEnv* env, jclass) {
1550 return env->NewStringUTF("not a class!");
1551}
1552
Andreas Gampe6e498692014-08-18 16:43:12 -07001553void JniCompilerTest::UpcallReturnTypeChecking_InstanceImpl() {
Vladimir Marko41c3de22022-12-07 15:42:12 +01001554 // Set debuggable so that the JNI compiler does not emit a fast-path that would skip the
1555 // runtime call where we do these checks. Note that while normal gtests use the debug build
1556 // which disables the fast path, `art_standalone_compiler_tests` run in the release build.
1557 compiler_options_->SetDebuggable(true);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001558 SetUpForTest(false, "instanceMethodThatShouldReturnClass", "()Ljava/lang/Class;",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001559 CURRENT_JNI_WRAPPER(Java_MyClassNatives_instanceMethodThatShouldReturnClass));
Elliott Hughesb264f082012-04-06 17:10:10 -07001560
1561 CheckJniAbortCatcher check_jni_abort_catcher;
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001562 // This native method is bad, and tries to return a jstring as a jclass.
1563 env_->CallObjectMethod(jobj_, jmethod_);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001564 check_jni_abort_catcher.Check(std::string() + "attempt to return an instance " +
1565 "of java.lang.String from java.lang.Class " +
1566 "MyClassNatives.instanceMethodThatShouldReturnClass" +
1567 CurrentJniStringSuffix() + "()");
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001568
1569 // Here, we just call the method incorrectly; we should catch that too.
Ian Rogers68d8b422014-07-17 11:09:10 -07001570 env_->CallObjectMethod(jobj_, jmethod_);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001571 check_jni_abort_catcher.Check(std::string() + "attempt to return an instance " +
1572 "of java.lang.String from java.lang.Class " +
1573 "MyClassNatives.instanceMethodThatShouldReturnClass" +
1574 CurrentJniStringSuffix() + "()");
Ian Rogers68d8b422014-07-17 11:09:10 -07001575 env_->CallStaticObjectMethod(jklass_, jmethod_);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001576 check_jni_abort_catcher.Check(std::string() + "calling non-static method " +
1577 "java.lang.Class " +
1578 "MyClassNatives.instanceMethodThatShouldReturnClass" +
1579 CurrentJniStringSuffix() + "() with CallStaticObjectMethodV");
Elliott Hughesb264f082012-04-06 17:10:10 -07001580}
1581
Igor Murashkinaf1e2992016-10-12 17:44:50 -07001582JNI_TEST(UpcallReturnTypeChecking_Instance)
Andreas Gampe6e498692014-08-18 16:43:12 -07001583
1584void JniCompilerTest::UpcallReturnTypeChecking_StaticImpl() {
Vladimir Marko41c3de22022-12-07 15:42:12 +01001585 // Set debuggable so that the JNI compiler does not emit a fast-path that would skip the
1586 // runtime call where we do these checks. Note that while normal gtests use the debug build
1587 // which disables the fast path, `art_standalone_compiler_tests` run in the release build.
1588 compiler_options_->SetDebuggable(true);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001589 SetUpForTest(true, "staticMethodThatShouldReturnClass", "()Ljava/lang/Class;",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001590 CURRENT_JNI_WRAPPER(Java_MyClassNatives_staticMethodThatShouldReturnClass));
Elliott Hughesb264f082012-04-06 17:10:10 -07001591
1592 CheckJniAbortCatcher check_jni_abort_catcher;
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001593 // This native method is bad, and tries to return a jstring as a jclass.
1594 env_->CallStaticObjectMethod(jklass_, jmethod_);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001595 check_jni_abort_catcher.Check(std::string() + "attempt to return an instance " +
1596 "of java.lang.String from java.lang.Class " +
1597 "MyClassNatives.staticMethodThatShouldReturnClass" +
1598 CurrentJniStringSuffix() + "()");
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001599
1600 // Here, we just call the method incorrectly; we should catch that too.
Ian Rogers68d8b422014-07-17 11:09:10 -07001601 env_->CallStaticObjectMethod(jklass_, jmethod_);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001602 check_jni_abort_catcher.Check(std::string() + "attempt to return an instance " +
1603 "of java.lang.String from java.lang.Class " +
1604 "MyClassNatives.staticMethodThatShouldReturnClass" +
1605 CurrentJniStringSuffix() + "()");
Ian Rogers68d8b422014-07-17 11:09:10 -07001606 env_->CallObjectMethod(jobj_, jmethod_);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001607 check_jni_abort_catcher.Check(std::string() + "calling static method " +
1608 "java.lang.Class " +
1609 "MyClassNatives.staticMethodThatShouldReturnClass" +
1610 CurrentJniStringSuffix() + "() with CallObjectMethodV");
Elliott Hughesb264f082012-04-06 17:10:10 -07001611}
1612
Igor Murashkinaf1e2992016-10-12 17:44:50 -07001613JNI_TEST(UpcallReturnTypeChecking_Static)
Andreas Gampe6e498692014-08-18 16:43:12 -07001614
Elliott Hughesb264f082012-04-06 17:10:10 -07001615// This should take jclass, but we're imitating a bug pattern.
1616void Java_MyClassNatives_instanceMethodThatShouldTakeClass(JNIEnv*, jobject, jclass) {
1617}
1618
1619// This should take jclass, but we're imitating a bug pattern.
1620void Java_MyClassNatives_staticMethodThatShouldTakeClass(JNIEnv*, jclass, jclass) {
1621}
1622
Andreas Gampe6e498692014-08-18 16:43:12 -07001623void JniCompilerTest::UpcallArgumentTypeChecking_InstanceImpl() {
Andreas Gampe369810a2015-01-14 19:53:31 -08001624 // This will lead to error messages in the log.
1625 ScopedLogSeverity sls(LogSeverity::FATAL);
1626
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001627 SetUpForTest(false, "instanceMethodThatShouldTakeClass", "(ILjava/lang/Class;)V",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001628 CURRENT_JNI_WRAPPER(Java_MyClassNatives_instanceMethodThatShouldTakeClass));
Elliott Hughesb264f082012-04-06 17:10:10 -07001629
1630 CheckJniAbortCatcher check_jni_abort_catcher;
1631 // We deliberately pass a bad second argument here.
1632 env_->CallVoidMethod(jobj_, jmethod_, 123, env_->NewStringUTF("not a class!"));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001633 check_jni_abort_catcher.Check(std::string() + "bad arguments passed to void " +
1634 "MyClassNatives.instanceMethodThatShouldTakeClass" +
1635 CurrentJniStringSuffix() + "(int, java.lang.Class)");
Elliott Hughesb264f082012-04-06 17:10:10 -07001636}
1637
Andreas Gampe6e498692014-08-18 16:43:12 -07001638JNI_TEST(UpcallArgumentTypeChecking_Instance)
1639
1640void JniCompilerTest::UpcallArgumentTypeChecking_StaticImpl() {
Andreas Gampe369810a2015-01-14 19:53:31 -08001641 // This will lead to error messages in the log.
1642 ScopedLogSeverity sls(LogSeverity::FATAL);
1643
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001644 SetUpForTest(true, "staticMethodThatShouldTakeClass", "(ILjava/lang/Class;)V",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001645 CURRENT_JNI_WRAPPER(Java_MyClassNatives_staticMethodThatShouldTakeClass));
Elliott Hughesb264f082012-04-06 17:10:10 -07001646
1647 CheckJniAbortCatcher check_jni_abort_catcher;
1648 // We deliberately pass a bad second argument here.
1649 env_->CallStaticVoidMethod(jklass_, jmethod_, 123, env_->NewStringUTF("not a class!"));
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001650 check_jni_abort_catcher.Check(std::string() + "bad arguments passed to void " +
1651 "MyClassNatives.staticMethodThatShouldTakeClass" +
1652 CurrentJniStringSuffix() + "(int, java.lang.Class)");
Elliott Hughesb264f082012-04-06 17:10:10 -07001653}
1654
Andreas Gampe6e498692014-08-18 16:43:12 -07001655JNI_TEST(UpcallArgumentTypeChecking_Static)
1656
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001657jfloat Java_MyClassNatives_checkFloats(JNIEnv*, jobject, jfloat f1, jfloat f2) {
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001658 return f1 - f2; // non-commutative operator
1659}
1660
Andreas Gampe6e498692014-08-18 16:43:12 -07001661void JniCompilerTest::CompileAndRunFloatFloatMethodImpl() {
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001662 SetUpForTest(false, "checkFloats", "(FF)F",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001663 CURRENT_JNI_WRAPPER(Java_MyClassNatives_checkFloats));
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001664
1665 jfloat result = env_->CallNonvirtualFloatMethod(jobj_, jklass_, jmethod_,
1666 99.0F, 10.0F);
Ian Rogers647b1a82014-10-10 11:02:11 -07001667 EXPECT_FLOAT_EQ(99.0F - 10.0F, result);
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001668 jfloat a = 3.14159F;
1669 jfloat b = 0.69314F;
1670 result = env_->CallNonvirtualFloatMethod(jobj_, jklass_, jmethod_, a, b);
Ian Rogers647b1a82014-10-10 11:02:11 -07001671 EXPECT_FLOAT_EQ(a - b, result);
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001672}
1673
Andreas Gampe6e498692014-08-18 16:43:12 -07001674JNI_TEST(CompileAndRunFloatFloatMethod)
1675
Stefano Cianciulli78f3c722023-05-16 10:32:54 +00001676void Java_MyClassNatives_checkParameterAlign([[maybe_unused]] JNIEnv* env,
1677 [[maybe_unused]] jobject thisObj,
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001678 jint i1,
1679 jlong l1) {
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001680 EXPECT_EQ(i1, 1234);
Ian Rogers0f678472014-03-10 16:18:37 -07001681 EXPECT_EQ(l1, INT64_C(0x12345678ABCDEF0));
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001682}
1683
Andreas Gampe6e498692014-08-18 16:43:12 -07001684void JniCompilerTest::CheckParameterAlignImpl() {
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001685 SetUpForTest(false, "checkParameterAlign", "(IJ)V",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001686 CURRENT_JNI_WRAPPER(Java_MyClassNatives_checkParameterAlign));
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001687
Ian Rogers0f678472014-03-10 16:18:37 -07001688 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_, 1234, INT64_C(0x12345678ABCDEF0));
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001689}
1690
Andreas Gampe6e498692014-08-18 16:43:12 -07001691JNI_TEST(CheckParameterAlign)
1692
Igor Murashkin367f3dd2016-09-01 17:00:24 -07001693void Java_MyClassNatives_maxParamNumber(JNIEnv* env, jobject,
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001694 jobject o0, jobject o1, jobject o2, jobject o3, jobject o4, jobject o5, jobject o6, jobject o7,
1695 jobject o8, jobject o9, jobject o10, jobject o11, jobject o12, jobject o13, jobject o14, jobject o15,
1696 jobject o16, jobject o17, jobject o18, jobject o19, jobject o20, jobject o21, jobject o22, jobject o23,
1697 jobject o24, jobject o25, jobject o26, jobject o27, jobject o28, jobject o29, jobject o30, jobject o31,
1698 jobject o32, jobject o33, jobject o34, jobject o35, jobject o36, jobject o37, jobject o38, jobject o39,
1699 jobject o40, jobject o41, jobject o42, jobject o43, jobject o44, jobject o45, jobject o46, jobject o47,
1700 jobject o48, jobject o49, jobject o50, jobject o51, jobject o52, jobject o53, jobject o54, jobject o55,
1701 jobject o56, jobject o57, jobject o58, jobject o59, jobject o60, jobject o61, jobject o62, jobject o63,
1702 jobject o64, jobject o65, jobject o66, jobject o67, jobject o68, jobject o69, jobject o70, jobject o71,
1703 jobject o72, jobject o73, jobject o74, jobject o75, jobject o76, jobject o77, jobject o78, jobject o79,
1704 jobject o80, jobject o81, jobject o82, jobject o83, jobject o84, jobject o85, jobject o86, jobject o87,
1705 jobject o88, jobject o89, jobject o90, jobject o91, jobject o92, jobject o93, jobject o94, jobject o95,
1706 jobject o96, jobject o97, jobject o98, jobject o99, jobject o100, jobject o101, jobject o102, jobject o103,
1707 jobject o104, jobject o105, jobject o106, jobject o107, jobject o108, jobject o109, jobject o110, jobject o111,
1708 jobject o112, jobject o113, jobject o114, jobject o115, jobject o116, jobject o117, jobject o118, jobject o119,
1709 jobject o120, jobject o121, jobject o122, jobject o123, jobject o124, jobject o125, jobject o126, jobject o127,
1710 jobject o128, jobject o129, jobject o130, jobject o131, jobject o132, jobject o133, jobject o134, jobject o135,
1711 jobject o136, jobject o137, jobject o138, jobject o139, jobject o140, jobject o141, jobject o142, jobject o143,
1712 jobject o144, jobject o145, jobject o146, jobject o147, jobject o148, jobject o149, jobject o150, jobject o151,
1713 jobject o152, jobject o153, jobject o154, jobject o155, jobject o156, jobject o157, jobject o158, jobject o159,
1714 jobject o160, jobject o161, jobject o162, jobject o163, jobject o164, jobject o165, jobject o166, jobject o167,
1715 jobject o168, jobject o169, jobject o170, jobject o171, jobject o172, jobject o173, jobject o174, jobject o175,
1716 jobject o176, jobject o177, jobject o178, jobject o179, jobject o180, jobject o181, jobject o182, jobject o183,
1717 jobject o184, jobject o185, jobject o186, jobject o187, jobject o188, jobject o189, jobject o190, jobject o191,
1718 jobject o192, jobject o193, jobject o194, jobject o195, jobject o196, jobject o197, jobject o198, jobject o199,
1719 jobject o200, jobject o201, jobject o202, jobject o203, jobject o204, jobject o205, jobject o206, jobject o207,
1720 jobject o208, jobject o209, jobject o210, jobject o211, jobject o212, jobject o213, jobject o214, jobject o215,
1721 jobject o216, jobject o217, jobject o218, jobject o219, jobject o220, jobject o221, jobject o222, jobject o223,
1722 jobject o224, jobject o225, jobject o226, jobject o227, jobject o228, jobject o229, jobject o230, jobject o231,
1723 jobject o232, jobject o233, jobject o234, jobject o235, jobject o236, jobject o237, jobject o238, jobject o239,
1724 jobject o240, jobject o241, jobject o242, jobject o243, jobject o244, jobject o245, jobject o246, jobject o247,
1725 jobject o248, jobject o249, jobject o250, jobject o251, jobject o252, jobject o253) {
Andreas Gampe7a0e5042014-03-07 13:03:19 -08001726 // two tests possible
1727 if (o0 == nullptr) {
1728 // 1) everything is null
1729 EXPECT_TRUE(o0 == nullptr && o1 == nullptr && o2 == nullptr && o3 == nullptr && o4 == nullptr
1730 && o5 == nullptr && o6 == nullptr && o7 == nullptr && o8 == nullptr && o9 == nullptr
1731 && o10 == nullptr && o11 == nullptr && o12 == nullptr && o13 == nullptr && o14 == nullptr
1732 && o15 == nullptr && o16 == nullptr && o17 == nullptr && o18 == nullptr && o19 == nullptr
1733 && o20 == nullptr && o21 == nullptr && o22 == nullptr && o23 == nullptr && o24 == nullptr
1734 && o25 == nullptr && o26 == nullptr && o27 == nullptr && o28 == nullptr && o29 == nullptr
1735 && o30 == nullptr && o31 == nullptr && o32 == nullptr && o33 == nullptr && o34 == nullptr
1736 && o35 == nullptr && o36 == nullptr && o37 == nullptr && o38 == nullptr && o39 == nullptr
1737 && o40 == nullptr && o41 == nullptr && o42 == nullptr && o43 == nullptr && o44 == nullptr
1738 && o45 == nullptr && o46 == nullptr && o47 == nullptr && o48 == nullptr && o49 == nullptr
1739 && o50 == nullptr && o51 == nullptr && o52 == nullptr && o53 == nullptr && o54 == nullptr
1740 && o55 == nullptr && o56 == nullptr && o57 == nullptr && o58 == nullptr && o59 == nullptr
1741 && o60 == nullptr && o61 == nullptr && o62 == nullptr && o63 == nullptr && o64 == nullptr
1742 && o65 == nullptr && o66 == nullptr && o67 == nullptr && o68 == nullptr && o69 == nullptr
1743 && o70 == nullptr && o71 == nullptr && o72 == nullptr && o73 == nullptr && o74 == nullptr
1744 && o75 == nullptr && o76 == nullptr && o77 == nullptr && o78 == nullptr && o79 == nullptr
1745 && o80 == nullptr && o81 == nullptr && o82 == nullptr && o83 == nullptr && o84 == nullptr
1746 && o85 == nullptr && o86 == nullptr && o87 == nullptr && o88 == nullptr && o89 == nullptr
1747 && o90 == nullptr && o91 == nullptr && o92 == nullptr && o93 == nullptr && o94 == nullptr
1748 && o95 == nullptr && o96 == nullptr && o97 == nullptr && o98 == nullptr && o99 == nullptr
1749 && o100 == nullptr && o101 == nullptr && o102 == nullptr && o103 == nullptr && o104 == nullptr
1750 && o105 == nullptr && o106 == nullptr && o107 == nullptr && o108 == nullptr && o109 == nullptr
1751 && o110 == nullptr && o111 == nullptr && o112 == nullptr && o113 == nullptr && o114 == nullptr
1752 && o115 == nullptr && o116 == nullptr && o117 == nullptr && o118 == nullptr && o119 == nullptr
1753 && o120 == nullptr && o121 == nullptr && o122 == nullptr && o123 == nullptr && o124 == nullptr
1754 && o125 == nullptr && o126 == nullptr && o127 == nullptr && o128 == nullptr && o129 == nullptr
1755 && o130 == nullptr && o131 == nullptr && o132 == nullptr && o133 == nullptr && o134 == nullptr
1756 && o135 == nullptr && o136 == nullptr && o137 == nullptr && o138 == nullptr && o139 == nullptr
1757 && o140 == nullptr && o141 == nullptr && o142 == nullptr && o143 == nullptr && o144 == nullptr
1758 && o145 == nullptr && o146 == nullptr && o147 == nullptr && o148 == nullptr && o149 == nullptr
1759 && o150 == nullptr && o151 == nullptr && o152 == nullptr && o153 == nullptr && o154 == nullptr
1760 && o155 == nullptr && o156 == nullptr && o157 == nullptr && o158 == nullptr && o159 == nullptr
1761 && o160 == nullptr && o161 == nullptr && o162 == nullptr && o163 == nullptr && o164 == nullptr
1762 && o165 == nullptr && o166 == nullptr && o167 == nullptr && o168 == nullptr && o169 == nullptr
1763 && o170 == nullptr && o171 == nullptr && o172 == nullptr && o173 == nullptr && o174 == nullptr
1764 && o175 == nullptr && o176 == nullptr && o177 == nullptr && o178 == nullptr && o179 == nullptr
1765 && o180 == nullptr && o181 == nullptr && o182 == nullptr && o183 == nullptr && o184 == nullptr
1766 && o185 == nullptr && o186 == nullptr && o187 == nullptr && o188 == nullptr && o189 == nullptr
1767 && o190 == nullptr && o191 == nullptr && o192 == nullptr && o193 == nullptr && o194 == nullptr
1768 && o195 == nullptr && o196 == nullptr && o197 == nullptr && o198 == nullptr && o199 == nullptr
1769 && o200 == nullptr && o201 == nullptr && o202 == nullptr && o203 == nullptr && o204 == nullptr
1770 && o205 == nullptr && o206 == nullptr && o207 == nullptr && o208 == nullptr && o209 == nullptr
1771 && o210 == nullptr && o211 == nullptr && o212 == nullptr && o213 == nullptr && o214 == nullptr
1772 && o215 == nullptr && o216 == nullptr && o217 == nullptr && o218 == nullptr && o219 == nullptr
1773 && o220 == nullptr && o221 == nullptr && o222 == nullptr && o223 == nullptr && o224 == nullptr
1774 && o225 == nullptr && o226 == nullptr && o227 == nullptr && o228 == nullptr && o229 == nullptr
1775 && o230 == nullptr && o231 == nullptr && o232 == nullptr && o233 == nullptr && o234 == nullptr
1776 && o235 == nullptr && o236 == nullptr && o237 == nullptr && o238 == nullptr && o239 == nullptr
1777 && o240 == nullptr && o241 == nullptr && o242 == nullptr && o243 == nullptr && o244 == nullptr
1778 && o245 == nullptr && o246 == nullptr && o247 == nullptr && o248 == nullptr && o249 == nullptr
1779 && o250 == nullptr && o251 == nullptr && o252 == nullptr && o253 == nullptr);
1780 } else {
1781 EXPECT_EQ(0, env->GetArrayLength(reinterpret_cast<jarray>(o0)));
1782 EXPECT_EQ(1, env->GetArrayLength(reinterpret_cast<jarray>(o1)));
1783 EXPECT_EQ(2, env->GetArrayLength(reinterpret_cast<jarray>(o2)));
1784 EXPECT_EQ(3, env->GetArrayLength(reinterpret_cast<jarray>(o3)));
1785 EXPECT_EQ(4, env->GetArrayLength(reinterpret_cast<jarray>(o4)));
1786 EXPECT_EQ(5, env->GetArrayLength(reinterpret_cast<jarray>(o5)));
1787 EXPECT_EQ(6, env->GetArrayLength(reinterpret_cast<jarray>(o6)));
1788 EXPECT_EQ(7, env->GetArrayLength(reinterpret_cast<jarray>(o7)));
1789 EXPECT_EQ(8, env->GetArrayLength(reinterpret_cast<jarray>(o8)));
1790 EXPECT_EQ(9, env->GetArrayLength(reinterpret_cast<jarray>(o9)));
1791 EXPECT_EQ(10, env->GetArrayLength(reinterpret_cast<jarray>(o10)));
1792 EXPECT_EQ(11, env->GetArrayLength(reinterpret_cast<jarray>(o11)));
1793 EXPECT_EQ(12, env->GetArrayLength(reinterpret_cast<jarray>(o12)));
1794 EXPECT_EQ(13, env->GetArrayLength(reinterpret_cast<jarray>(o13)));
1795 EXPECT_EQ(14, env->GetArrayLength(reinterpret_cast<jarray>(o14)));
1796 EXPECT_EQ(15, env->GetArrayLength(reinterpret_cast<jarray>(o15)));
1797 EXPECT_EQ(16, env->GetArrayLength(reinterpret_cast<jarray>(o16)));
1798 EXPECT_EQ(17, env->GetArrayLength(reinterpret_cast<jarray>(o17)));
1799 EXPECT_EQ(18, env->GetArrayLength(reinterpret_cast<jarray>(o18)));
1800 EXPECT_EQ(19, env->GetArrayLength(reinterpret_cast<jarray>(o19)));
1801 EXPECT_EQ(20, env->GetArrayLength(reinterpret_cast<jarray>(o20)));
1802 EXPECT_EQ(21, env->GetArrayLength(reinterpret_cast<jarray>(o21)));
1803 EXPECT_EQ(22, env->GetArrayLength(reinterpret_cast<jarray>(o22)));
1804 EXPECT_EQ(23, env->GetArrayLength(reinterpret_cast<jarray>(o23)));
1805 EXPECT_EQ(24, env->GetArrayLength(reinterpret_cast<jarray>(o24)));
1806 EXPECT_EQ(25, env->GetArrayLength(reinterpret_cast<jarray>(o25)));
1807 EXPECT_EQ(26, env->GetArrayLength(reinterpret_cast<jarray>(o26)));
1808 EXPECT_EQ(27, env->GetArrayLength(reinterpret_cast<jarray>(o27)));
1809 EXPECT_EQ(28, env->GetArrayLength(reinterpret_cast<jarray>(o28)));
1810 EXPECT_EQ(29, env->GetArrayLength(reinterpret_cast<jarray>(o29)));
1811 EXPECT_EQ(30, env->GetArrayLength(reinterpret_cast<jarray>(o30)));
1812 EXPECT_EQ(31, env->GetArrayLength(reinterpret_cast<jarray>(o31)));
1813 EXPECT_EQ(32, env->GetArrayLength(reinterpret_cast<jarray>(o32)));
1814 EXPECT_EQ(33, env->GetArrayLength(reinterpret_cast<jarray>(o33)));
1815 EXPECT_EQ(34, env->GetArrayLength(reinterpret_cast<jarray>(o34)));
1816 EXPECT_EQ(35, env->GetArrayLength(reinterpret_cast<jarray>(o35)));
1817 EXPECT_EQ(36, env->GetArrayLength(reinterpret_cast<jarray>(o36)));
1818 EXPECT_EQ(37, env->GetArrayLength(reinterpret_cast<jarray>(o37)));
1819 EXPECT_EQ(38, env->GetArrayLength(reinterpret_cast<jarray>(o38)));
1820 EXPECT_EQ(39, env->GetArrayLength(reinterpret_cast<jarray>(o39)));
1821 EXPECT_EQ(40, env->GetArrayLength(reinterpret_cast<jarray>(o40)));
1822 EXPECT_EQ(41, env->GetArrayLength(reinterpret_cast<jarray>(o41)));
1823 EXPECT_EQ(42, env->GetArrayLength(reinterpret_cast<jarray>(o42)));
1824 EXPECT_EQ(43, env->GetArrayLength(reinterpret_cast<jarray>(o43)));
1825 EXPECT_EQ(44, env->GetArrayLength(reinterpret_cast<jarray>(o44)));
1826 EXPECT_EQ(45, env->GetArrayLength(reinterpret_cast<jarray>(o45)));
1827 EXPECT_EQ(46, env->GetArrayLength(reinterpret_cast<jarray>(o46)));
1828 EXPECT_EQ(47, env->GetArrayLength(reinterpret_cast<jarray>(o47)));
1829 EXPECT_EQ(48, env->GetArrayLength(reinterpret_cast<jarray>(o48)));
1830 EXPECT_EQ(49, env->GetArrayLength(reinterpret_cast<jarray>(o49)));
1831 EXPECT_EQ(50, env->GetArrayLength(reinterpret_cast<jarray>(o50)));
1832 EXPECT_EQ(51, env->GetArrayLength(reinterpret_cast<jarray>(o51)));
1833 EXPECT_EQ(52, env->GetArrayLength(reinterpret_cast<jarray>(o52)));
1834 EXPECT_EQ(53, env->GetArrayLength(reinterpret_cast<jarray>(o53)));
1835 EXPECT_EQ(54, env->GetArrayLength(reinterpret_cast<jarray>(o54)));
1836 EXPECT_EQ(55, env->GetArrayLength(reinterpret_cast<jarray>(o55)));
1837 EXPECT_EQ(56, env->GetArrayLength(reinterpret_cast<jarray>(o56)));
1838 EXPECT_EQ(57, env->GetArrayLength(reinterpret_cast<jarray>(o57)));
1839 EXPECT_EQ(58, env->GetArrayLength(reinterpret_cast<jarray>(o58)));
1840 EXPECT_EQ(59, env->GetArrayLength(reinterpret_cast<jarray>(o59)));
1841 EXPECT_EQ(60, env->GetArrayLength(reinterpret_cast<jarray>(o60)));
1842 EXPECT_EQ(61, env->GetArrayLength(reinterpret_cast<jarray>(o61)));
1843 EXPECT_EQ(62, env->GetArrayLength(reinterpret_cast<jarray>(o62)));
1844 EXPECT_EQ(63, env->GetArrayLength(reinterpret_cast<jarray>(o63)));
1845 EXPECT_EQ(64, env->GetArrayLength(reinterpret_cast<jarray>(o64)));
1846 EXPECT_EQ(65, env->GetArrayLength(reinterpret_cast<jarray>(o65)));
1847 EXPECT_EQ(66, env->GetArrayLength(reinterpret_cast<jarray>(o66)));
1848 EXPECT_EQ(67, env->GetArrayLength(reinterpret_cast<jarray>(o67)));
1849 EXPECT_EQ(68, env->GetArrayLength(reinterpret_cast<jarray>(o68)));
1850 EXPECT_EQ(69, env->GetArrayLength(reinterpret_cast<jarray>(o69)));
1851 EXPECT_EQ(70, env->GetArrayLength(reinterpret_cast<jarray>(o70)));
1852 EXPECT_EQ(71, env->GetArrayLength(reinterpret_cast<jarray>(o71)));
1853 EXPECT_EQ(72, env->GetArrayLength(reinterpret_cast<jarray>(o72)));
1854 EXPECT_EQ(73, env->GetArrayLength(reinterpret_cast<jarray>(o73)));
1855 EXPECT_EQ(74, env->GetArrayLength(reinterpret_cast<jarray>(o74)));
1856 EXPECT_EQ(75, env->GetArrayLength(reinterpret_cast<jarray>(o75)));
1857 EXPECT_EQ(76, env->GetArrayLength(reinterpret_cast<jarray>(o76)));
1858 EXPECT_EQ(77, env->GetArrayLength(reinterpret_cast<jarray>(o77)));
1859 EXPECT_EQ(78, env->GetArrayLength(reinterpret_cast<jarray>(o78)));
1860 EXPECT_EQ(79, env->GetArrayLength(reinterpret_cast<jarray>(o79)));
1861 EXPECT_EQ(80, env->GetArrayLength(reinterpret_cast<jarray>(o80)));
1862 EXPECT_EQ(81, env->GetArrayLength(reinterpret_cast<jarray>(o81)));
1863 EXPECT_EQ(82, env->GetArrayLength(reinterpret_cast<jarray>(o82)));
1864 EXPECT_EQ(83, env->GetArrayLength(reinterpret_cast<jarray>(o83)));
1865 EXPECT_EQ(84, env->GetArrayLength(reinterpret_cast<jarray>(o84)));
1866 EXPECT_EQ(85, env->GetArrayLength(reinterpret_cast<jarray>(o85)));
1867 EXPECT_EQ(86, env->GetArrayLength(reinterpret_cast<jarray>(o86)));
1868 EXPECT_EQ(87, env->GetArrayLength(reinterpret_cast<jarray>(o87)));
1869 EXPECT_EQ(88, env->GetArrayLength(reinterpret_cast<jarray>(o88)));
1870 EXPECT_EQ(89, env->GetArrayLength(reinterpret_cast<jarray>(o89)));
1871 EXPECT_EQ(90, env->GetArrayLength(reinterpret_cast<jarray>(o90)));
1872 EXPECT_EQ(91, env->GetArrayLength(reinterpret_cast<jarray>(o91)));
1873 EXPECT_EQ(92, env->GetArrayLength(reinterpret_cast<jarray>(o92)));
1874 EXPECT_EQ(93, env->GetArrayLength(reinterpret_cast<jarray>(o93)));
1875 EXPECT_EQ(94, env->GetArrayLength(reinterpret_cast<jarray>(o94)));
1876 EXPECT_EQ(95, env->GetArrayLength(reinterpret_cast<jarray>(o95)));
1877 EXPECT_EQ(96, env->GetArrayLength(reinterpret_cast<jarray>(o96)));
1878 EXPECT_EQ(97, env->GetArrayLength(reinterpret_cast<jarray>(o97)));
1879 EXPECT_EQ(98, env->GetArrayLength(reinterpret_cast<jarray>(o98)));
1880 EXPECT_EQ(99, env->GetArrayLength(reinterpret_cast<jarray>(o99)));
1881 EXPECT_EQ(100, env->GetArrayLength(reinterpret_cast<jarray>(o100)));
1882 EXPECT_EQ(101, env->GetArrayLength(reinterpret_cast<jarray>(o101)));
1883 EXPECT_EQ(102, env->GetArrayLength(reinterpret_cast<jarray>(o102)));
1884 EXPECT_EQ(103, env->GetArrayLength(reinterpret_cast<jarray>(o103)));
1885 EXPECT_EQ(104, env->GetArrayLength(reinterpret_cast<jarray>(o104)));
1886 EXPECT_EQ(105, env->GetArrayLength(reinterpret_cast<jarray>(o105)));
1887 EXPECT_EQ(106, env->GetArrayLength(reinterpret_cast<jarray>(o106)));
1888 EXPECT_EQ(107, env->GetArrayLength(reinterpret_cast<jarray>(o107)));
1889 EXPECT_EQ(108, env->GetArrayLength(reinterpret_cast<jarray>(o108)));
1890 EXPECT_EQ(109, env->GetArrayLength(reinterpret_cast<jarray>(o109)));
1891 EXPECT_EQ(110, env->GetArrayLength(reinterpret_cast<jarray>(o110)));
1892 EXPECT_EQ(111, env->GetArrayLength(reinterpret_cast<jarray>(o111)));
1893 EXPECT_EQ(112, env->GetArrayLength(reinterpret_cast<jarray>(o112)));
1894 EXPECT_EQ(113, env->GetArrayLength(reinterpret_cast<jarray>(o113)));
1895 EXPECT_EQ(114, env->GetArrayLength(reinterpret_cast<jarray>(o114)));
1896 EXPECT_EQ(115, env->GetArrayLength(reinterpret_cast<jarray>(o115)));
1897 EXPECT_EQ(116, env->GetArrayLength(reinterpret_cast<jarray>(o116)));
1898 EXPECT_EQ(117, env->GetArrayLength(reinterpret_cast<jarray>(o117)));
1899 EXPECT_EQ(118, env->GetArrayLength(reinterpret_cast<jarray>(o118)));
1900 EXPECT_EQ(119, env->GetArrayLength(reinterpret_cast<jarray>(o119)));
1901 EXPECT_EQ(120, env->GetArrayLength(reinterpret_cast<jarray>(o120)));
1902 EXPECT_EQ(121, env->GetArrayLength(reinterpret_cast<jarray>(o121)));
1903 EXPECT_EQ(122, env->GetArrayLength(reinterpret_cast<jarray>(o122)));
1904 EXPECT_EQ(123, env->GetArrayLength(reinterpret_cast<jarray>(o123)));
1905 EXPECT_EQ(124, env->GetArrayLength(reinterpret_cast<jarray>(o124)));
1906 EXPECT_EQ(125, env->GetArrayLength(reinterpret_cast<jarray>(o125)));
1907 EXPECT_EQ(126, env->GetArrayLength(reinterpret_cast<jarray>(o126)));
1908 EXPECT_EQ(127, env->GetArrayLength(reinterpret_cast<jarray>(o127)));
1909 EXPECT_EQ(128, env->GetArrayLength(reinterpret_cast<jarray>(o128)));
1910 EXPECT_EQ(129, env->GetArrayLength(reinterpret_cast<jarray>(o129)));
1911 EXPECT_EQ(130, env->GetArrayLength(reinterpret_cast<jarray>(o130)));
1912 EXPECT_EQ(131, env->GetArrayLength(reinterpret_cast<jarray>(o131)));
1913 EXPECT_EQ(132, env->GetArrayLength(reinterpret_cast<jarray>(o132)));
1914 EXPECT_EQ(133, env->GetArrayLength(reinterpret_cast<jarray>(o133)));
1915 EXPECT_EQ(134, env->GetArrayLength(reinterpret_cast<jarray>(o134)));
1916 EXPECT_EQ(135, env->GetArrayLength(reinterpret_cast<jarray>(o135)));
1917 EXPECT_EQ(136, env->GetArrayLength(reinterpret_cast<jarray>(o136)));
1918 EXPECT_EQ(137, env->GetArrayLength(reinterpret_cast<jarray>(o137)));
1919 EXPECT_EQ(138, env->GetArrayLength(reinterpret_cast<jarray>(o138)));
1920 EXPECT_EQ(139, env->GetArrayLength(reinterpret_cast<jarray>(o139)));
1921 EXPECT_EQ(140, env->GetArrayLength(reinterpret_cast<jarray>(o140)));
1922 EXPECT_EQ(141, env->GetArrayLength(reinterpret_cast<jarray>(o141)));
1923 EXPECT_EQ(142, env->GetArrayLength(reinterpret_cast<jarray>(o142)));
1924 EXPECT_EQ(143, env->GetArrayLength(reinterpret_cast<jarray>(o143)));
1925 EXPECT_EQ(144, env->GetArrayLength(reinterpret_cast<jarray>(o144)));
1926 EXPECT_EQ(145, env->GetArrayLength(reinterpret_cast<jarray>(o145)));
1927 EXPECT_EQ(146, env->GetArrayLength(reinterpret_cast<jarray>(o146)));
1928 EXPECT_EQ(147, env->GetArrayLength(reinterpret_cast<jarray>(o147)));
1929 EXPECT_EQ(148, env->GetArrayLength(reinterpret_cast<jarray>(o148)));
1930 EXPECT_EQ(149, env->GetArrayLength(reinterpret_cast<jarray>(o149)));
1931 EXPECT_EQ(150, env->GetArrayLength(reinterpret_cast<jarray>(o150)));
1932 EXPECT_EQ(151, env->GetArrayLength(reinterpret_cast<jarray>(o151)));
1933 EXPECT_EQ(152, env->GetArrayLength(reinterpret_cast<jarray>(o152)));
1934 EXPECT_EQ(153, env->GetArrayLength(reinterpret_cast<jarray>(o153)));
1935 EXPECT_EQ(154, env->GetArrayLength(reinterpret_cast<jarray>(o154)));
1936 EXPECT_EQ(155, env->GetArrayLength(reinterpret_cast<jarray>(o155)));
1937 EXPECT_EQ(156, env->GetArrayLength(reinterpret_cast<jarray>(o156)));
1938 EXPECT_EQ(157, env->GetArrayLength(reinterpret_cast<jarray>(o157)));
1939 EXPECT_EQ(158, env->GetArrayLength(reinterpret_cast<jarray>(o158)));
1940 EXPECT_EQ(159, env->GetArrayLength(reinterpret_cast<jarray>(o159)));
1941 EXPECT_EQ(160, env->GetArrayLength(reinterpret_cast<jarray>(o160)));
1942 EXPECT_EQ(161, env->GetArrayLength(reinterpret_cast<jarray>(o161)));
1943 EXPECT_EQ(162, env->GetArrayLength(reinterpret_cast<jarray>(o162)));
1944 EXPECT_EQ(163, env->GetArrayLength(reinterpret_cast<jarray>(o163)));
1945 EXPECT_EQ(164, env->GetArrayLength(reinterpret_cast<jarray>(o164)));
1946 EXPECT_EQ(165, env->GetArrayLength(reinterpret_cast<jarray>(o165)));
1947 EXPECT_EQ(166, env->GetArrayLength(reinterpret_cast<jarray>(o166)));
1948 EXPECT_EQ(167, env->GetArrayLength(reinterpret_cast<jarray>(o167)));
1949 EXPECT_EQ(168, env->GetArrayLength(reinterpret_cast<jarray>(o168)));
1950 EXPECT_EQ(169, env->GetArrayLength(reinterpret_cast<jarray>(o169)));
1951 EXPECT_EQ(170, env->GetArrayLength(reinterpret_cast<jarray>(o170)));
1952 EXPECT_EQ(171, env->GetArrayLength(reinterpret_cast<jarray>(o171)));
1953 EXPECT_EQ(172, env->GetArrayLength(reinterpret_cast<jarray>(o172)));
1954 EXPECT_EQ(173, env->GetArrayLength(reinterpret_cast<jarray>(o173)));
1955 EXPECT_EQ(174, env->GetArrayLength(reinterpret_cast<jarray>(o174)));
1956 EXPECT_EQ(175, env->GetArrayLength(reinterpret_cast<jarray>(o175)));
1957 EXPECT_EQ(176, env->GetArrayLength(reinterpret_cast<jarray>(o176)));
1958 EXPECT_EQ(177, env->GetArrayLength(reinterpret_cast<jarray>(o177)));
1959 EXPECT_EQ(178, env->GetArrayLength(reinterpret_cast<jarray>(o178)));
1960 EXPECT_EQ(179, env->GetArrayLength(reinterpret_cast<jarray>(o179)));
1961 EXPECT_EQ(180, env->GetArrayLength(reinterpret_cast<jarray>(o180)));
1962 EXPECT_EQ(181, env->GetArrayLength(reinterpret_cast<jarray>(o181)));
1963 EXPECT_EQ(182, env->GetArrayLength(reinterpret_cast<jarray>(o182)));
1964 EXPECT_EQ(183, env->GetArrayLength(reinterpret_cast<jarray>(o183)));
1965 EXPECT_EQ(184, env->GetArrayLength(reinterpret_cast<jarray>(o184)));
1966 EXPECT_EQ(185, env->GetArrayLength(reinterpret_cast<jarray>(o185)));
1967 EXPECT_EQ(186, env->GetArrayLength(reinterpret_cast<jarray>(o186)));
1968 EXPECT_EQ(187, env->GetArrayLength(reinterpret_cast<jarray>(o187)));
1969 EXPECT_EQ(188, env->GetArrayLength(reinterpret_cast<jarray>(o188)));
1970 EXPECT_EQ(189, env->GetArrayLength(reinterpret_cast<jarray>(o189)));
1971 EXPECT_EQ(190, env->GetArrayLength(reinterpret_cast<jarray>(o190)));
1972 EXPECT_EQ(191, env->GetArrayLength(reinterpret_cast<jarray>(o191)));
1973 EXPECT_EQ(192, env->GetArrayLength(reinterpret_cast<jarray>(o192)));
1974 EXPECT_EQ(193, env->GetArrayLength(reinterpret_cast<jarray>(o193)));
1975 EXPECT_EQ(194, env->GetArrayLength(reinterpret_cast<jarray>(o194)));
1976 EXPECT_EQ(195, env->GetArrayLength(reinterpret_cast<jarray>(o195)));
1977 EXPECT_EQ(196, env->GetArrayLength(reinterpret_cast<jarray>(o196)));
1978 EXPECT_EQ(197, env->GetArrayLength(reinterpret_cast<jarray>(o197)));
1979 EXPECT_EQ(198, env->GetArrayLength(reinterpret_cast<jarray>(o198)));
1980 EXPECT_EQ(199, env->GetArrayLength(reinterpret_cast<jarray>(o199)));
1981 EXPECT_EQ(200, env->GetArrayLength(reinterpret_cast<jarray>(o200)));
1982 EXPECT_EQ(201, env->GetArrayLength(reinterpret_cast<jarray>(o201)));
1983 EXPECT_EQ(202, env->GetArrayLength(reinterpret_cast<jarray>(o202)));
1984 EXPECT_EQ(203, env->GetArrayLength(reinterpret_cast<jarray>(o203)));
1985 EXPECT_EQ(204, env->GetArrayLength(reinterpret_cast<jarray>(o204)));
1986 EXPECT_EQ(205, env->GetArrayLength(reinterpret_cast<jarray>(o205)));
1987 EXPECT_EQ(206, env->GetArrayLength(reinterpret_cast<jarray>(o206)));
1988 EXPECT_EQ(207, env->GetArrayLength(reinterpret_cast<jarray>(o207)));
1989 EXPECT_EQ(208, env->GetArrayLength(reinterpret_cast<jarray>(o208)));
1990 EXPECT_EQ(209, env->GetArrayLength(reinterpret_cast<jarray>(o209)));
1991 EXPECT_EQ(210, env->GetArrayLength(reinterpret_cast<jarray>(o210)));
1992 EXPECT_EQ(211, env->GetArrayLength(reinterpret_cast<jarray>(o211)));
1993 EXPECT_EQ(212, env->GetArrayLength(reinterpret_cast<jarray>(o212)));
1994 EXPECT_EQ(213, env->GetArrayLength(reinterpret_cast<jarray>(o213)));
1995 EXPECT_EQ(214, env->GetArrayLength(reinterpret_cast<jarray>(o214)));
1996 EXPECT_EQ(215, env->GetArrayLength(reinterpret_cast<jarray>(o215)));
1997 EXPECT_EQ(216, env->GetArrayLength(reinterpret_cast<jarray>(o216)));
1998 EXPECT_EQ(217, env->GetArrayLength(reinterpret_cast<jarray>(o217)));
1999 EXPECT_EQ(218, env->GetArrayLength(reinterpret_cast<jarray>(o218)));
2000 EXPECT_EQ(219, env->GetArrayLength(reinterpret_cast<jarray>(o219)));
2001 EXPECT_EQ(220, env->GetArrayLength(reinterpret_cast<jarray>(o220)));
2002 EXPECT_EQ(221, env->GetArrayLength(reinterpret_cast<jarray>(o221)));
2003 EXPECT_EQ(222, env->GetArrayLength(reinterpret_cast<jarray>(o222)));
2004 EXPECT_EQ(223, env->GetArrayLength(reinterpret_cast<jarray>(o223)));
2005 EXPECT_EQ(224, env->GetArrayLength(reinterpret_cast<jarray>(o224)));
2006 EXPECT_EQ(225, env->GetArrayLength(reinterpret_cast<jarray>(o225)));
2007 EXPECT_EQ(226, env->GetArrayLength(reinterpret_cast<jarray>(o226)));
2008 EXPECT_EQ(227, env->GetArrayLength(reinterpret_cast<jarray>(o227)));
2009 EXPECT_EQ(228, env->GetArrayLength(reinterpret_cast<jarray>(o228)));
2010 EXPECT_EQ(229, env->GetArrayLength(reinterpret_cast<jarray>(o229)));
2011 EXPECT_EQ(230, env->GetArrayLength(reinterpret_cast<jarray>(o230)));
2012 EXPECT_EQ(231, env->GetArrayLength(reinterpret_cast<jarray>(o231)));
2013 EXPECT_EQ(232, env->GetArrayLength(reinterpret_cast<jarray>(o232)));
2014 EXPECT_EQ(233, env->GetArrayLength(reinterpret_cast<jarray>(o233)));
2015 EXPECT_EQ(234, env->GetArrayLength(reinterpret_cast<jarray>(o234)));
2016 EXPECT_EQ(235, env->GetArrayLength(reinterpret_cast<jarray>(o235)));
2017 EXPECT_EQ(236, env->GetArrayLength(reinterpret_cast<jarray>(o236)));
2018 EXPECT_EQ(237, env->GetArrayLength(reinterpret_cast<jarray>(o237)));
2019 EXPECT_EQ(238, env->GetArrayLength(reinterpret_cast<jarray>(o238)));
2020 EXPECT_EQ(239, env->GetArrayLength(reinterpret_cast<jarray>(o239)));
2021 EXPECT_EQ(240, env->GetArrayLength(reinterpret_cast<jarray>(o240)));
2022 EXPECT_EQ(241, env->GetArrayLength(reinterpret_cast<jarray>(o241)));
2023 EXPECT_EQ(242, env->GetArrayLength(reinterpret_cast<jarray>(o242)));
2024 EXPECT_EQ(243, env->GetArrayLength(reinterpret_cast<jarray>(o243)));
2025 EXPECT_EQ(244, env->GetArrayLength(reinterpret_cast<jarray>(o244)));
2026 EXPECT_EQ(245, env->GetArrayLength(reinterpret_cast<jarray>(o245)));
2027 EXPECT_EQ(246, env->GetArrayLength(reinterpret_cast<jarray>(o246)));
2028 EXPECT_EQ(247, env->GetArrayLength(reinterpret_cast<jarray>(o247)));
2029 EXPECT_EQ(248, env->GetArrayLength(reinterpret_cast<jarray>(o248)));
2030 EXPECT_EQ(249, env->GetArrayLength(reinterpret_cast<jarray>(o249)));
2031 EXPECT_EQ(250, env->GetArrayLength(reinterpret_cast<jarray>(o250)));
2032 EXPECT_EQ(251, env->GetArrayLength(reinterpret_cast<jarray>(o251)));
2033 EXPECT_EQ(252, env->GetArrayLength(reinterpret_cast<jarray>(o252)));
2034 EXPECT_EQ(253, env->GetArrayLength(reinterpret_cast<jarray>(o253)));
2035 }
2036}
2037
2038const char* longSig =
2039 "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2040 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2041 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2042 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2043 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2044 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2045 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2046 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2047 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2048 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2049 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2050 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2051 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2052 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2053 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2054 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2055 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2056 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2057 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2058 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2059 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2060 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2061 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2062 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2063 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2064 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2065 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2066 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2067 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2068 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2069 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2070 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2071 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2072 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2073 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2074 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2075 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2076 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2077 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2078 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2079 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2080 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2081 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2082 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2083 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2084 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2085 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2086 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2087 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2088 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;"
2089 "Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V";
2090
Andreas Gampe6e498692014-08-18 16:43:12 -07002091void JniCompilerTest::MaxParamNumberImpl() {
Andreas Gampe7a0e5042014-03-07 13:03:19 -08002092 SetUpForTest(false, "maxParamNumber", longSig,
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002093 CURRENT_JNI_WRAPPER(Java_MyClassNatives_maxParamNumber));
Andreas Gampe7a0e5042014-03-07 13:03:19 -08002094
2095 jvalue args[254];
2096
2097 // First test: test with all arguments null.
2098 for (int i = 0; i < 254; ++i) {
2099 args[i].l = nullptr;
2100 }
2101
2102 env_->CallNonvirtualVoidMethodA(jobj_, jklass_, jmethod_, args);
2103
2104 // Second test: test with int[] objects with increasing lengths
2105 for (int i = 0; i < 254; ++i) {
2106 jintArray tmp = env_->NewIntArray(i);
2107 args[i].l = tmp;
2108 EXPECT_NE(args[i].l, nullptr);
2109 }
2110
2111 env_->CallNonvirtualVoidMethodA(jobj_, jklass_, jmethod_, args);
2112}
2113
Andreas Gampe6e498692014-08-18 16:43:12 -07002114JNI_TEST(MaxParamNumber)
2115
2116void JniCompilerTest::WithoutImplementationImpl() {
Andreas Gampe369810a2015-01-14 19:53:31 -08002117 // This will lead to error messages in the log.
2118 ScopedLogSeverity sls(LogSeverity::FATAL);
2119
Vladimir Markofa458ac2020-02-12 14:08:07 +00002120 SetUpForTest(false, "withoutImplementation", "()V", NORMAL_OR_FAST_JNI_ONLY_NULLPTR);
Andreas Gampead615172014-04-04 16:20:13 -07002121
2122 env_->CallVoidMethod(jobj_, jmethod_);
2123
2124 EXPECT_TRUE(Thread::Current()->IsExceptionPending());
2125 EXPECT_TRUE(env_->ExceptionCheck() == JNI_TRUE);
2126}
2127
Vladimir Markofa458ac2020-02-12 14:08:07 +00002128JNI_TEST(WithoutImplementation)
Andreas Gampe6e498692014-08-18 16:43:12 -07002129
Andreas Gampe48ee3562015-04-10 19:57:29 -07002130void JniCompilerTest::WithoutImplementationRefReturnImpl() {
2131 // This will lead to error messages in the log.
2132 ScopedLogSeverity sls(LogSeverity::FATAL);
2133
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002134 SetUpForTest(false,
2135 "withoutImplementationRefReturn",
2136 "()Ljava/lang/Object;",
Vladimir Markofa458ac2020-02-12 14:08:07 +00002137 NORMAL_OR_FAST_JNI_ONLY_NULLPTR);
Andreas Gampe48ee3562015-04-10 19:57:29 -07002138
2139 env_->CallObjectMethod(jobj_, jmethod_);
2140
2141 EXPECT_TRUE(Thread::Current()->IsExceptionPending());
2142 EXPECT_TRUE(env_->ExceptionCheck() == JNI_TRUE);
2143}
2144
Vladimir Markofa458ac2020-02-12 14:08:07 +00002145JNI_TEST(WithoutImplementationRefReturn)
2146
2147void JniCompilerTest::StaticWithoutImplementationImpl() {
2148 // This will lead to error messages in the log.
2149 ScopedLogSeverity sls(LogSeverity::FATAL);
2150
2151 SetUpForTest(true, "staticWithoutImplementation", "()V", nullptr);
2152
2153 env_->CallStaticVoidMethod(jklass_, jmethod_);
2154
2155 EXPECT_TRUE(Thread::Current()->IsExceptionPending());
2156 EXPECT_TRUE(env_->ExceptionCheck() == JNI_TRUE);
2157}
2158
2159JNI_TEST_CRITICAL(StaticWithoutImplementation)
Andreas Gampe48ee3562015-04-10 19:57:29 -07002160
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07002161void Java_MyClassNatives_stackArgsIntsFirst(JNIEnv*, jclass, jint i1, jint i2, jint i3,
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002162 jint i4, jint i5, jint i6, jint i7, jint i8, jint i9,
2163 jint i10, jfloat f1, jfloat f2, jfloat f3, jfloat f4,
2164 jfloat f5, jfloat f6, jfloat f7, jfloat f8, jfloat f9,
2165 jfloat f10) {
2166 EXPECT_EQ(i1, 1);
2167 EXPECT_EQ(i2, 2);
2168 EXPECT_EQ(i3, 3);
2169 EXPECT_EQ(i4, 4);
2170 EXPECT_EQ(i5, 5);
2171 EXPECT_EQ(i6, 6);
2172 EXPECT_EQ(i7, 7);
2173 EXPECT_EQ(i8, 8);
2174 EXPECT_EQ(i9, 9);
2175 EXPECT_EQ(i10, 10);
2176
Roland Levillainda4d79b2015-03-24 14:36:11 +00002177 jint i11 = bit_cast<jint, jfloat>(f1);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002178 EXPECT_EQ(i11, 11);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002179 jint i12 = bit_cast<jint, jfloat>(f2);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002180 EXPECT_EQ(i12, 12);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002181 jint i13 = bit_cast<jint, jfloat>(f3);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002182 EXPECT_EQ(i13, 13);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002183 jint i14 = bit_cast<jint, jfloat>(f4);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002184 EXPECT_EQ(i14, 14);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002185 jint i15 = bit_cast<jint, jfloat>(f5);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002186 EXPECT_EQ(i15, 15);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002187 jint i16 = bit_cast<jint, jfloat>(f6);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002188 EXPECT_EQ(i16, 16);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002189 jint i17 = bit_cast<jint, jfloat>(f7);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002190 EXPECT_EQ(i17, 17);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002191 jint i18 = bit_cast<jint, jfloat>(f8);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002192 EXPECT_EQ(i18, 18);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002193 jint i19 = bit_cast<jint, jfloat>(f9);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002194 EXPECT_EQ(i19, 19);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002195 jint i20 = bit_cast<jint, jfloat>(f10);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002196 EXPECT_EQ(i20, 20);
2197}
2198
Andreas Gampe6e498692014-08-18 16:43:12 -07002199void JniCompilerTest::StackArgsIntsFirstImpl() {
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002200 SetUpForTest(true, "stackArgsIntsFirst", "(IIIIIIIIIIFFFFFFFFFF)V",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002201 CURRENT_JNI_WRAPPER(Java_MyClassNatives_stackArgsIntsFirst));
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002202
2203 jint i1 = 1;
2204 jint i2 = 2;
2205 jint i3 = 3;
2206 jint i4 = 4;
2207 jint i5 = 5;
2208 jint i6 = 6;
2209 jint i7 = 7;
2210 jint i8 = 8;
2211 jint i9 = 9;
2212 jint i10 = 10;
2213
Roland Levillainda4d79b2015-03-24 14:36:11 +00002214 jfloat f1 = bit_cast<jfloat, jint>(11);
2215 jfloat f2 = bit_cast<jfloat, jint>(12);
2216 jfloat f3 = bit_cast<jfloat, jint>(13);
2217 jfloat f4 = bit_cast<jfloat, jint>(14);
2218 jfloat f5 = bit_cast<jfloat, jint>(15);
2219 jfloat f6 = bit_cast<jfloat, jint>(16);
2220 jfloat f7 = bit_cast<jfloat, jint>(17);
2221 jfloat f8 = bit_cast<jfloat, jint>(18);
2222 jfloat f9 = bit_cast<jfloat, jint>(19);
2223 jfloat f10 = bit_cast<jfloat, jint>(20);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002224
2225 env_->CallStaticVoidMethod(jklass_, jmethod_, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, f1, f2,
2226 f3, f4, f5, f6, f7, f8, f9, f10);
2227}
2228
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002229JNI_TEST_CRITICAL(StackArgsIntsFirst)
Andreas Gampe6e498692014-08-18 16:43:12 -07002230
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07002231void Java_MyClassNatives_stackArgsFloatsFirst(JNIEnv*, jclass, jfloat f1, jfloat f2,
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002232 jfloat f3, jfloat f4, jfloat f5, jfloat f6, jfloat f7,
2233 jfloat f8, jfloat f9, jfloat f10, jint i1, jint i2,
2234 jint i3, jint i4, jint i5, jint i6, jint i7, jint i8,
2235 jint i9, jint i10) {
2236 EXPECT_EQ(i1, 1);
2237 EXPECT_EQ(i2, 2);
2238 EXPECT_EQ(i3, 3);
2239 EXPECT_EQ(i4, 4);
2240 EXPECT_EQ(i5, 5);
2241 EXPECT_EQ(i6, 6);
2242 EXPECT_EQ(i7, 7);
2243 EXPECT_EQ(i8, 8);
2244 EXPECT_EQ(i9, 9);
2245 EXPECT_EQ(i10, 10);
2246
Roland Levillainda4d79b2015-03-24 14:36:11 +00002247 jint i11 = bit_cast<jint, jfloat>(f1);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002248 EXPECT_EQ(i11, 11);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002249 jint i12 = bit_cast<jint, jfloat>(f2);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002250 EXPECT_EQ(i12, 12);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002251 jint i13 = bit_cast<jint, jfloat>(f3);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002252 EXPECT_EQ(i13, 13);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002253 jint i14 = bit_cast<jint, jfloat>(f4);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002254 EXPECT_EQ(i14, 14);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002255 jint i15 = bit_cast<jint, jfloat>(f5);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002256 EXPECT_EQ(i15, 15);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002257 jint i16 = bit_cast<jint, jfloat>(f6);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002258 EXPECT_EQ(i16, 16);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002259 jint i17 = bit_cast<jint, jfloat>(f7);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002260 EXPECT_EQ(i17, 17);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002261 jint i18 = bit_cast<jint, jfloat>(f8);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002262 EXPECT_EQ(i18, 18);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002263 jint i19 = bit_cast<jint, jfloat>(f9);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002264 EXPECT_EQ(i19, 19);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002265 jint i20 = bit_cast<jint, jfloat>(f10);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002266 EXPECT_EQ(i20, 20);
2267}
2268
Andreas Gampe6e498692014-08-18 16:43:12 -07002269void JniCompilerTest::StackArgsFloatsFirstImpl() {
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002270 SetUpForTest(true, "stackArgsFloatsFirst", "(FFFFFFFFFFIIIIIIIIII)V",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002271 CURRENT_JNI_WRAPPER(Java_MyClassNatives_stackArgsFloatsFirst));
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002272
2273 jint i1 = 1;
2274 jint i2 = 2;
2275 jint i3 = 3;
2276 jint i4 = 4;
2277 jint i5 = 5;
2278 jint i6 = 6;
2279 jint i7 = 7;
2280 jint i8 = 8;
2281 jint i9 = 9;
2282 jint i10 = 10;
2283
Roland Levillainda4d79b2015-03-24 14:36:11 +00002284 jfloat f1 = bit_cast<jfloat, jint>(11);
2285 jfloat f2 = bit_cast<jfloat, jint>(12);
2286 jfloat f3 = bit_cast<jfloat, jint>(13);
2287 jfloat f4 = bit_cast<jfloat, jint>(14);
2288 jfloat f5 = bit_cast<jfloat, jint>(15);
2289 jfloat f6 = bit_cast<jfloat, jint>(16);
2290 jfloat f7 = bit_cast<jfloat, jint>(17);
2291 jfloat f8 = bit_cast<jfloat, jint>(18);
2292 jfloat f9 = bit_cast<jfloat, jint>(19);
2293 jfloat f10 = bit_cast<jfloat, jint>(20);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002294
2295 env_->CallStaticVoidMethod(jklass_, jmethod_, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, i1, i2, i3,
2296 i4, i5, i6, i7, i8, i9, i10);
2297}
2298
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002299JNI_TEST_CRITICAL(StackArgsFloatsFirst)
Andreas Gampe6e498692014-08-18 16:43:12 -07002300
Ian Rogers6a3c1fc2014-10-31 00:33:20 -07002301void Java_MyClassNatives_stackArgsMixed(JNIEnv*, jclass, jint i1, jfloat f1, jint i2,
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002302 jfloat f2, jint i3, jfloat f3, jint i4, jfloat f4, jint i5,
2303 jfloat f5, jint i6, jfloat f6, jint i7, jfloat f7, jint i8,
2304 jfloat f8, jint i9, jfloat f9, jint i10, jfloat f10) {
2305 EXPECT_EQ(i1, 1);
2306 EXPECT_EQ(i2, 2);
2307 EXPECT_EQ(i3, 3);
2308 EXPECT_EQ(i4, 4);
2309 EXPECT_EQ(i5, 5);
2310 EXPECT_EQ(i6, 6);
2311 EXPECT_EQ(i7, 7);
2312 EXPECT_EQ(i8, 8);
2313 EXPECT_EQ(i9, 9);
2314 EXPECT_EQ(i10, 10);
2315
Roland Levillainda4d79b2015-03-24 14:36:11 +00002316 jint i11 = bit_cast<jint, jfloat>(f1);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002317 EXPECT_EQ(i11, 11);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002318 jint i12 = bit_cast<jint, jfloat>(f2);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002319 EXPECT_EQ(i12, 12);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002320 jint i13 = bit_cast<jint, jfloat>(f3);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002321 EXPECT_EQ(i13, 13);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002322 jint i14 = bit_cast<jint, jfloat>(f4);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002323 EXPECT_EQ(i14, 14);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002324 jint i15 = bit_cast<jint, jfloat>(f5);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002325 EXPECT_EQ(i15, 15);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002326 jint i16 = bit_cast<jint, jfloat>(f6);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002327 EXPECT_EQ(i16, 16);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002328 jint i17 = bit_cast<jint, jfloat>(f7);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002329 EXPECT_EQ(i17, 17);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002330 jint i18 = bit_cast<jint, jfloat>(f8);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002331 EXPECT_EQ(i18, 18);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002332 jint i19 = bit_cast<jint, jfloat>(f9);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002333 EXPECT_EQ(i19, 19);
Roland Levillainda4d79b2015-03-24 14:36:11 +00002334 jint i20 = bit_cast<jint, jfloat>(f10);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002335 EXPECT_EQ(i20, 20);
2336}
2337
Andreas Gampe6e498692014-08-18 16:43:12 -07002338void JniCompilerTest::StackArgsMixedImpl() {
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002339 SetUpForTest(true, "stackArgsMixed", "(IFIFIFIFIFIFIFIFIFIF)V",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002340 CURRENT_JNI_WRAPPER(Java_MyClassNatives_stackArgsMixed));
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002341
2342 jint i1 = 1;
2343 jint i2 = 2;
2344 jint i3 = 3;
2345 jint i4 = 4;
2346 jint i5 = 5;
2347 jint i6 = 6;
2348 jint i7 = 7;
2349 jint i8 = 8;
2350 jint i9 = 9;
2351 jint i10 = 10;
2352
Roland Levillainda4d79b2015-03-24 14:36:11 +00002353 jfloat f1 = bit_cast<jfloat, jint>(11);
2354 jfloat f2 = bit_cast<jfloat, jint>(12);
2355 jfloat f3 = bit_cast<jfloat, jint>(13);
2356 jfloat f4 = bit_cast<jfloat, jint>(14);
2357 jfloat f5 = bit_cast<jfloat, jint>(15);
2358 jfloat f6 = bit_cast<jfloat, jint>(16);
2359 jfloat f7 = bit_cast<jfloat, jint>(17);
2360 jfloat f8 = bit_cast<jfloat, jint>(18);
2361 jfloat f9 = bit_cast<jfloat, jint>(19);
2362 jfloat f10 = bit_cast<jfloat, jint>(20);
Vladimir Kostyukov1dd61ba2014-04-02 18:42:20 +07002363
2364 env_->CallStaticVoidMethod(jklass_, jmethod_, i1, f1, i2, f2, i3, f3, i4, f4, i5, f5, i6, f6, i7,
2365 f7, i8, f8, i9, f9, i10, f10);
2366}
2367
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002368JNI_TEST_CRITICAL(StackArgsMixed)
Andreas Gampe6e498692014-08-18 16:43:12 -07002369
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002370void Java_MyClassNatives_normalNative(JNIEnv*, jclass) {
2371 // Intentionally left empty.
2372}
2373
2374// Methods not annotated with anything are not considered "fast native"
2375// -- Check that the annotation lookup does not find it.
2376void JniCompilerTest::NormalNativeImpl() {
Andreas Gampe3db70682018-12-26 15:12:03 -08002377 SetUpForTest(/* direct= */ true,
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002378 "normalNative",
2379 "()V",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002380 CURRENT_JNI_WRAPPER(Java_MyClassNatives_normalNative));
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002381
Andreas Gampe13b27842016-11-07 16:48:23 -08002382 ArtMethod* method = jni::DecodeArtMethod(jmethod_);
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002383 ASSERT_TRUE(method != nullptr);
2384
Vladimir Markob0a6aee2017-10-27 10:34:04 +01002385 EXPECT_FALSE(method->IsCriticalNative());
2386 EXPECT_FALSE(method->IsFastNative());
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002387}
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002388
2389// TODO: just rename the java functions to the standard convention and remove duplicated tests
2390JNI_TEST_NORMAL_ONLY(NormalNative)
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002391
2392// Methods annotated with @FastNative are considered "fast native"
2393// -- Check that the annotation lookup succeeds.
2394void Java_MyClassNatives_fastNative(JNIEnv*, jclass) {
2395 // Intentionally left empty.
2396}
2397
2398void JniCompilerTest::FastNativeImpl() {
Andreas Gampe3db70682018-12-26 15:12:03 -08002399 SetUpForTest(/* direct= */ true,
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002400 "fastNative",
2401 "()V",
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002402 CURRENT_JNI_WRAPPER(Java_MyClassNatives_fastNative));
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002403
Andreas Gampe13b27842016-11-07 16:48:23 -08002404 ArtMethod* method = jni::DecodeArtMethod(jmethod_);
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002405 ASSERT_TRUE(method != nullptr);
2406
Vladimir Markob0a6aee2017-10-27 10:34:04 +01002407 EXPECT_FALSE(method->IsCriticalNative());
2408 EXPECT_TRUE(method->IsFastNative());
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002409}
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002410
2411// TODO: just rename the java functions to the standard convention and remove duplicated tests
2412JNI_TEST_NORMAL_ONLY(FastNative)
2413
2414int gJava_myClassNatives_criticalNative_calls[kJniKindCount] = {};
2415// Methods annotated with @CriticalNative are considered "critical native"
2416// -- Check that the annotation lookup succeeds.
2417void Java_MyClassNatives_criticalNative() {
2418 gJava_myClassNatives_criticalNative_calls[gCurrentJni]++;
2419}
2420
2421void JniCompilerTest::CriticalNativeImpl() {
Andreas Gampe3db70682018-12-26 15:12:03 -08002422 SetUpForTest(/* direct= */ true,
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002423 // Important: Don't change the "current jni" yet to avoid a method name suffix.
2424 "criticalNative",
2425 "()V",
2426 // TODO: Use CURRENT_JNI_WRAPPER instead which is more generic.
2427 reinterpret_cast<void*>(&Java_MyClassNatives_criticalNative));
2428
2429 // TODO: remove this manual updating of the current JNI. Merge with the other tests.
2430 UpdateCurrentJni(JniKind::kCritical);
2431 ASSERT_TRUE(IsCurrentJniCritical());
2432
Andreas Gampe13b27842016-11-07 16:48:23 -08002433 ArtMethod* method = jni::DecodeArtMethod(jmethod_);
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002434 ASSERT_TRUE(method != nullptr);
2435
Vladimir Markob0a6aee2017-10-27 10:34:04 +01002436 EXPECT_TRUE(method->IsCriticalNative());
2437 EXPECT_FALSE(method->IsFastNative());
Igor Murashkin367f3dd2016-09-01 17:00:24 -07002438
2439 EXPECT_EQ(0, gJava_myClassNatives_criticalNative_calls[gCurrentJni]);
2440 env_->CallStaticVoidMethod(jklass_, jmethod_);
2441 EXPECT_EQ(1, gJava_myClassNatives_criticalNative_calls[gCurrentJni]);
2442
2443 gJava_myClassNatives_criticalNative_calls[gCurrentJni] = 0;
2444}
2445
2446// TODO: just rename the java functions to the standard convention and remove duplicated tests
2447JNI_TEST_NORMAL_ONLY(CriticalNative)
Igor Murashkin9d4b6da2016-07-29 09:51:58 -07002448
Ian Rogersb033c752011-07-20 12:22:35 -07002449} // namespace art