blob: 43b99127ec76200acf97474f02c5c0c5625dc833 [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 Rogersdf20fe02011-07-20 20:34:16 -070016
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070017#include "jni_internal.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070018
Elliott Hughes0af55432011-08-17 18:37:28 -070019#include <dlfcn.h>
Elliott Hughes79082e32011-08-25 12:07:32 -070020
21#include <cstdarg>
Ian Rogers700a4022014-05-19 16:49:03 -070022#include <memory>
Elliott Hughes0af55432011-08-17 18:37:28 -070023#include <utility>
24#include <vector>
Carl Shapiro2ed144c2011-07-26 16:52:08 -070025
Ian Rogersef7d42f2014-01-06 12:55:46 -080026#include "atomic.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080027#include "base/logging.h"
Elliott Hughes76b61672012-12-12 17:47:30 -080028#include "base/mutex.h"
Elliott Hughes1aa246d2012-12-13 09:29:36 -080029#include "base/stl_util.h"
Ian Rogers98379392014-02-24 16:53:16 -080030#include "class_linker-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070031#include "dex_file-inl.h"
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -070032#include "gc_root.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070033#include "gc/accounting/card_table-inl.h"
Mathieu Chartierc56057e2014-05-04 13:18:58 -070034#include "indirect_reference_table-inl.h"
Jeff Hao3dd9f762013-07-08 13:09:25 -070035#include "interpreter/interpreter.h"
Carl Shapiroea4dca82011-08-01 13:45:38 -070036#include "jni.h"
Brian Carlstromea46f952013-07-30 01:26:50 -070037#include "mirror/art_field-inl.h"
38#include "mirror/art_method-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080039#include "mirror/class-inl.h"
40#include "mirror/class_loader.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080041#include "mirror/object-inl.h"
42#include "mirror/object_array-inl.h"
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070043#include "mirror/string-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080044#include "mirror/throwable.h"
Yong WU355383f2014-07-24 21:32:15 +080045#include "native_bridge.h"
Brian Carlstrom491ca9e2014-03-02 18:24:38 -080046#include "parsed_options.h"
Ian Rogers53b8b092014-03-13 23:45:53 -070047#include "reflection.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070048#include "runtime.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070049#include "safe_map.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070050#include "scoped_thread_state_change.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070051#include "ScopedLocalRef.h"
Carl Shapiro2ed144c2011-07-26 16:52:08 -070052#include "thread.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080053#include "utf.h"
Elliott Hugheseac76672012-05-24 21:56:51 -070054#include "well_known_classes.h"
Ian Rogersdf20fe02011-07-20 20:34:16 -070055
Elliott Hughesbb1e8f02011-10-18 14:14:25 -070056namespace art {
57
Brian Carlstrom7934ac22013-07-26 10:54:15 -070058static const size_t kMonitorsInitial = 32; // Arbitrary.
59static const size_t kMonitorsMax = 4096; // Arbitrary sanity check.
Elliott Hughes2ced6a52011-10-16 18:44:48 -070060
Brian Carlstrom7934ac22013-07-26 10:54:15 -070061static const size_t kLocalsInitial = 64; // Arbitrary.
62static const size_t kLocalsMax = 512; // Arbitrary sanity check.
Elliott Hughes2ced6a52011-10-16 18:44:48 -070063
Brian Carlstrom7934ac22013-07-26 10:54:15 -070064static const size_t kPinTableInitial = 16; // Arbitrary.
65static const size_t kPinTableMax = 1024; // Arbitrary sanity check.
Elliott Hughes2ced6a52011-10-16 18:44:48 -070066
Brian Carlstrom7934ac22013-07-26 10:54:15 -070067static size_t gGlobalsInitial = 512; // Arbitrary.
68static size_t gGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.)
Elliott Hughes2ced6a52011-10-16 18:44:48 -070069
Brian Carlstrom7934ac22013-07-26 10:54:15 -070070static const size_t kWeakGlobalsInitial = 16; // Arbitrary.
71static const size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.)
Ian Rogersdf20fe02011-07-20 20:34:16 -070072
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -080073static jweak AddWeakGlobalReference(ScopedObjectAccess& soa, mirror::Object* obj)
Ian Rogersb726dcb2012-09-05 08:57:23 -070074 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartierc11d9b82013-09-19 10:01:59 -070075 return soa.Vm()->AddWeakGlobalReference(soa.Self(), obj);
Elliott Hughescdf53122011-08-19 15:46:09 -070076}
77
Jeff Hao19c5d372013-03-15 14:33:43 -070078static bool IsBadJniVersion(int version) {
79 // We don't support JNI_VERSION_1_1. These are the only other valid versions.
80 return version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 && version != JNI_VERSION_1_6;
81}
82
Elliott Hughes6b436852011-08-12 10:16:44 -070083// Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
84// separated with slashes but aren't wrapped with "L;" like regular descriptors
85// (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
86// exception; there the "L;" must be present ("[La/b/C;"). Historically we've
87// supported names with dots too (such as "a.b.C").
Ian Rogers0571d352011-11-03 19:51:38 -070088static std::string NormalizeJniClassDescriptor(const char* name) {
Elliott Hughes6b436852011-08-12 10:16:44 -070089 std::string result;
90 // Add the missing "L;" if necessary.
91 if (name[0] == '[') {
92 result = name;
93 } else {
94 result += 'L';
95 result += name;
96 result += ';';
97 }
98 // Rewrite '.' as '/' for backwards compatibility.
Elliott Hughesa5b897e2011-08-16 11:33:06 -070099 if (result.find('.') != std::string::npos) {
100 LOG(WARNING) << "Call to JNI FindClass with dots in name: "
101 << "\"" << name << "\"";
102 std::replace(result.begin(), result.end(), '.', '/');
Elliott Hughes6b436852011-08-12 10:16:44 -0700103 }
104 return result;
105}
106
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800107static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, mirror::Class* c,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700108 const char* name, const char* sig, const char* kind)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700109 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800110 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
111 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchMethodError;",
112 "no %s method \"%s.%s%s\"",
Mathieu Chartierf8322842014-05-16 10:59:25 -0700113 kind, c->GetDescriptor().c_str(), name, sig);
Elliott Hughes14134a12011-09-30 16:55:51 -0700114}
115
Sebastien Hertzfa65e842014-07-03 09:39:53 +0200116static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa, mirror::Class* c,
117 const char* kind, jint idx, bool return_errors)
118 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
119 LOG(return_errors ? ERROR : FATAL) << "Failed to register native method in "
120 << PrettyDescriptor(c) << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
121 << ": " << kind << " is null at index " << idx;
122 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
123 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchMethodError;",
124 "%s is null at index %d", kind, idx);
125}
126
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800127static mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass)
128 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
129 if (LIKELY(klass->IsInitialized())) {
130 return klass;
131 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700132 StackHandleScope<1> hs(self);
133 Handle<mirror::Class> h_klass(hs.NewHandle(klass));
134 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(h_klass, true, true)) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800135 return nullptr;
136 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700137 return h_klass.Get();
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800138}
139
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700140static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
141 const char* name, const char* sig, bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700142 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800143 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800144 if (c == nullptr) {
145 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700146 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800147 mirror::ArtMethod* method = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -0700148 if (is_static) {
149 method = c->FindDirectMethod(name, sig);
Brian Carlstrom004644f2014-06-18 08:34:01 -0700150 } else if (c->IsInterface()) {
151 method = c->FindInterfaceMethod(name, sig);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700152 } else {
Elliott Hughescdf53122011-08-19 15:46:09 -0700153 method = c->FindVirtualMethod(name, sig);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800154 if (method == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700155 // No virtual method matching the signature. Search declared
156 // private methods and constructors.
157 method = c->FindDeclaredDirectMethod(name, sig);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700158 }
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700159 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800160 if (method == nullptr || method->IsStatic() != is_static) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700161 ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800162 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -0700163 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700164 return soa.EncodeMethod(method);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700165}
166
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800167static mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700168 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800169 mirror::ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
Brian Carlstromce888532013-10-10 00:32:58 -0700170 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
171 if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
Ian Rogersef28b142012-11-30 14:22:18 -0800172 return soa.Self()->GetClassLoaderOverride();
Brian Carlstrom00fae582011-10-28 01:16:28 -0700173 }
Brian Carlstromce888532013-10-10 00:32:58 -0700174 // If we have a method, use its ClassLoader for context.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800175 if (method != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700176 return method->GetDeclaringClass()->GetClassLoader();
177 }
178 // We don't have a method, so try to use the system ClassLoader.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800179 mirror::ClassLoader* class_loader =
180 soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
181 if (class_loader != nullptr) {
Brian Carlstromce888532013-10-10 00:32:58 -0700182 return class_loader;
183 }
184 // See if the override ClassLoader is set for gtests.
185 class_loader = soa.Self()->GetClassLoaderOverride();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800186 if (class_loader != nullptr) {
Brian Carlstroma1ce1fe2014-02-24 23:23:58 -0800187 // If so, CommonCompilerTest should have set UseCompileTimeClassPath.
Brian Carlstromce888532013-10-10 00:32:58 -0700188 CHECK(Runtime::Current()->UseCompileTimeClassPath());
189 return class_loader;
190 }
191 // Use the BOOTCLASSPATH.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800192 return nullptr;
Brian Carlstrom00fae582011-10-28 01:16:28 -0700193}
194
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700195static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
196 const char* sig, bool is_static)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700197 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700198 StackHandleScope<2> hs(soa.Self());
199 Handle<mirror::Class> c(
200 hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class))));
201 if (c.Get() == nullptr) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800202 return nullptr;
Carl Shapiro83ab4f32011-08-15 20:21:39 -0700203 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800204 mirror::ArtField* field = nullptr;
205 mirror::Class* field_type;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700206 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
207 if (sig[1] != '\0') {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700208 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
Ian Rogers98379392014-02-24 16:53:16 -0800209 field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700210 } else {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700211 field_type = class_linker->FindPrimitiveClass(*sig);
Carl Shapiro9b9ba282011-08-14 15:30:39 -0700212 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800213 if (field_type == nullptr) {
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700214 // Failed to find type from the signature of the field.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700215 DCHECK(soa.Self()->IsExceptionPending());
Ian Rogers62d6c772013-02-27 08:32:07 -0800216 ThrowLocation throw_location;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700217 StackHandleScope<1> hs(soa.Self());
218 Handle<mirror::Throwable> cause(hs.NewHandle(soa.Self()->GetException(&throw_location)));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700219 soa.Self()->ClearException();
Ian Rogers62d6c772013-02-27 08:32:07 -0800220 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800221 "no type \"%s\" found and so no field \"%s\" "
222 "could be found in class \"%s\" or its superclasses", sig, name,
Mathieu Chartierf8322842014-05-16 10:59:25 -0700223 c->GetDescriptor().c_str());
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700224 soa.Self()->GetException(nullptr)->SetCause(cause.Get());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800225 return nullptr;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700226 }
227 if (is_static) {
Mathieu Chartierf8322842014-05-16 10:59:25 -0700228 field = mirror::Class::FindStaticField(soa.Self(), c, name,
229 field_type->GetDescriptor().c_str());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700230 } else {
Mathieu Chartierf8322842014-05-16 10:59:25 -0700231 field = c->FindInstanceField(name, field_type->GetDescriptor().c_str());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700232 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800233 if (field == nullptr) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800234 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
235 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
236 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
Mathieu Chartierf8322842014-05-16 10:59:25 -0700237 sig, name, c->GetDescriptor().c_str());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800238 return nullptr;
Elliott Hughes8a26c5c2011-08-15 18:35:43 -0700239 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700240 return soa.EncodeField(field);
Carl Shapiroea4dca82011-08-01 13:45:38 -0700241}
242
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800243static void PinPrimitiveArray(const ScopedObjectAccess& soa, mirror::Array* array)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700244 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700245 JavaVMExt* vm = soa.Vm();
Ian Rogers50b35e22012-10-04 10:09:15 -0700246 MutexLock mu(soa.Self(), vm->pins_lock);
Elliott Hughes75770752011-08-24 17:52:38 -0700247 vm->pin_table.Add(array);
248}
249
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800250static void UnpinPrimitiveArray(const ScopedObjectAccess& soa, mirror::Array* array)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700251 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700252 JavaVMExt* vm = soa.Vm();
Ian Rogers50b35e22012-10-04 10:09:15 -0700253 MutexLock mu(soa.Self(), vm->pins_lock);
Elliott Hughes75770752011-08-24 17:52:38 -0700254 vm->pin_table.Remove(array);
255}
256
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800257static void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700258 jsize length, const char* identifier)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700259 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes54e7df12011-09-16 11:47:04 -0700260 std::string type(PrettyTypeOf(array));
Ian Rogers62d6c772013-02-27 08:32:07 -0800261 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
262 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayIndexOutOfBoundsException;",
263 "%s offset=%d length=%d %s.length=%d",
264 type.c_str(), start, length, identifier, array->GetLength());
Elliott Hughes814e4032011-08-23 12:07:56 -0700265}
Ian Rogers0571d352011-11-03 19:51:38 -0700266
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700267static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
268 jsize array_length)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700269 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800270 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
271 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/StringIndexOutOfBoundsException;",
272 "offset=%d length=%d string.length()=%d", start, length,
273 array_length);
Elliott Hughesb465ab02011-08-24 11:21:21 -0700274}
Elliott Hughes814e4032011-08-23 12:07:56 -0700275
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700276int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700277 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700278 // Turn the const char* into a java.lang.String.
279 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800280 if (msg != nullptr && s.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700281 return JNI_ERR;
Elliott Hughes814e4032011-08-23 12:07:56 -0700282 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700283
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700284 // Choose an appropriate constructor and set up the arguments.
285 jvalue args[2];
286 const char* signature;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800287 if (msg == nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700288 signature = "()V";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800289 } else if (msg != nullptr && cause == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700290 signature = "(Ljava/lang/String;)V";
291 args[0].l = s.get();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800292 } else if (msg == nullptr && cause != nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700293 signature = "(Ljava/lang/Throwable;)V";
294 args[0].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700295 } else {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700296 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
297 args[0].l = s.get();
298 args[1].l = cause;
Elliott Hughes814e4032011-08-23 12:07:56 -0700299 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700300 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800301 if (mid == nullptr) {
Ian Rogersef28b142012-11-30 14:22:18 -0800302 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700303 LOG(ERROR) << "No <init>" << signature << " in "
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800304 << PrettyClass(soa.Decode<mirror::Class*>(exception_class));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700305 return JNI_ERR;
306 }
Elliott Hughes814e4032011-08-23 12:07:56 -0700307
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800308 ScopedLocalRef<jthrowable> exception(
309 env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
310 if (exception.get() == nullptr) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700311 return JNI_ERR;
312 }
Ian Rogersef28b142012-11-30 14:22:18 -0800313 ScopedObjectAccess soa(env);
Ian Rogers62d6c772013-02-27 08:32:07 -0800314 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800315 soa.Self()->SetException(throw_location, soa.Decode<mirror::Throwable*>(exception.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700316 return JNI_OK;
Elliott Hughesa4f94742012-05-29 16:28:38 -0700317}
318
Elliott Hughes462c9442012-03-23 18:47:50 -0700319static jint JII_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800320 if (vm == nullptr || p_env == nullptr) {
Elliott Hughes75770752011-08-24 17:52:38 -0700321 return JNI_ERR;
322 }
323
Elliott Hughes462c9442012-03-23 18:47:50 -0700324 // Return immediately if we're already attached.
Elliott Hughescac6cc72011-11-03 20:31:21 -0700325 Thread* self = Thread::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800326 if (self != nullptr) {
Elliott Hughescac6cc72011-11-03 20:31:21 -0700327 *p_env = self->GetJniEnv();
328 return JNI_OK;
329 }
330
331 Runtime* runtime = reinterpret_cast<JavaVMExt*>(vm)->runtime;
332
333 // No threads allowed in zygote mode.
334 if (runtime->IsZygote()) {
335 LOG(ERROR) << "Attempt to attach a thread in the zygote";
336 return JNI_ERR;
337 }
338
Elliott Hughes462c9442012-03-23 18:47:50 -0700339 JavaVMAttachArgs* args = static_cast<JavaVMAttachArgs*>(raw_args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800340 const char* thread_name = nullptr;
341 jobject thread_group = nullptr;
342 if (args != nullptr) {
Elliott Hughes83a25322013-03-14 11:18:53 -0700343 if (IsBadJniVersion(args->version)) {
344 LOG(ERROR) << "Bad JNI version passed to "
345 << (as_daemon ? "AttachCurrentThreadAsDaemon" : "AttachCurrentThread") << ": "
346 << args->version;
347 return JNI_EVERSION;
Brian Carlstrom86922152013-03-12 00:59:36 -0700348 }
Elliott Hughes462c9442012-03-23 18:47:50 -0700349 thread_name = args->name;
Ian Rogers365c1022012-06-22 15:05:28 -0700350 thread_group = args->group;
Elliott Hughes75770752011-08-24 17:52:38 -0700351 }
Elliott Hughes75770752011-08-24 17:52:38 -0700352
Mathieu Chartier664bebf2012-11-12 16:54:11 -0800353 if (!runtime->AttachCurrentThread(thread_name, as_daemon, thread_group, !runtime->IsCompiler())) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800354 *p_env = nullptr;
Ian Rogers120f1c72012-09-28 17:17:10 -0700355 return JNI_ERR;
356 } else {
357 *p_env = Thread::Current()->GetJniEnv();
358 return JNI_OK;
359 }
Elliott Hughes75770752011-08-24 17:52:38 -0700360}
361
Elliott Hughes79082e32011-08-25 12:07:32 -0700362class SharedLibrary {
363 public:
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800364 SharedLibrary(const std::string& path, void* handle, mirror::Object* class_loader)
Elliott Hughes79082e32011-08-25 12:07:32 -0700365 : path_(path),
366 handle_(handle),
Yong WU355383f2014-07-24 21:32:15 +0800367 needs_native_bridge_(false),
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -0700368 class_loader_(GcRoot<mirror::Object>(class_loader)),
Elliott Hughes8daa0922011-09-11 13:46:25 -0700369 jni_on_load_lock_("JNI_OnLoad lock"),
Ian Rogersc604d732012-10-14 16:09:54 -0700370 jni_on_load_cond_("JNI_OnLoad condition variable", jni_on_load_lock_),
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700371 jni_on_load_thread_id_(Thread::Current()->GetThreadId()),
Elliott Hughes79082e32011-08-25 12:07:32 -0700372 jni_on_load_result_(kPending) {
Elliott Hughes79082e32011-08-25 12:07:32 -0700373 }
374
Hiroshi Yamauchiea2e1bd2014-06-18 13:47:35 -0700375 mirror::Object* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -0700376 return class_loader_.Read();
Elliott Hughes79082e32011-08-25 12:07:32 -0700377 }
378
379 std::string GetPath() {
380 return path_;
381 }
382
383 /*
Elliott Hughes1bac54f2012-03-16 12:48:31 -0700384 * Check the result of an earlier call to JNI_OnLoad on this library.
385 * If the call has not yet finished in another thread, wait for it.
Elliott Hughes79082e32011-08-25 12:07:32 -0700386 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700387 bool CheckOnLoadResult()
388 LOCKS_EXCLUDED(jni_on_load_lock_)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700389 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes79082e32011-08-25 12:07:32 -0700390 Thread* self = Thread::Current();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700391 self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
392 bool okay;
393 {
Ian Rogers50b35e22012-10-04 10:09:15 -0700394 MutexLock mu(self, jni_on_load_lock_);
Elliott Hughes79082e32011-08-25 12:07:32 -0700395
Ian Rogersd9c4fc92013-10-01 19:45:43 -0700396 if (jni_on_load_thread_id_ == self->GetThreadId()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700397 // Check this so we don't end up waiting for ourselves. We need to return "true" so the
398 // caller can continue.
399 LOG(INFO) << *self << " recursive attempt to load library " << "\"" << path_ << "\"";
400 okay = true;
401 } else {
402 while (jni_on_load_result_ == kPending) {
403 VLOG(jni) << "[" << *self << " waiting for \"" << path_ << "\" " << "JNI_OnLoad...]";
Ian Rogersc604d732012-10-14 16:09:54 -0700404 jni_on_load_cond_.Wait(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700405 }
Elliott Hughes79082e32011-08-25 12:07:32 -0700406
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700407 okay = (jni_on_load_result_ == kOkay);
408 VLOG(jni) << "[Earlier JNI_OnLoad for \"" << path_ << "\" "
409 << (okay ? "succeeded" : "failed") << "]";
410 }
411 }
412 self->TransitionFromSuspendedToRunnable();
Elliott Hughes79082e32011-08-25 12:07:32 -0700413 return okay;
414 }
415
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700416 void SetResult(bool result) LOCKS_EXCLUDED(jni_on_load_lock_) {
Ian Rogersc604d732012-10-14 16:09:54 -0700417 Thread* self = Thread::Current();
418 MutexLock mu(self, jni_on_load_lock_);
Elliott Hughesf8349362012-06-18 15:00:06 -0700419
Elliott Hughes79082e32011-08-25 12:07:32 -0700420 jni_on_load_result_ = result ? kOkay : kFailed;
Elliott Hughesdcc24742011-09-07 14:02:44 -0700421 jni_on_load_thread_id_ = 0;
Elliott Hughes79082e32011-08-25 12:07:32 -0700422
423 // Broadcast a wakeup to anybody sleeping on the condition variable.
Ian Rogersc604d732012-10-14 16:09:54 -0700424 jni_on_load_cond_.Broadcast(self);
Elliott Hughes79082e32011-08-25 12:07:32 -0700425 }
426
Yong WU355383f2014-07-24 21:32:15 +0800427 void SetNeedsNativeBridge() {
428 needs_native_bridge_ = true;
429 }
430
431 bool NeedsNativeBridge() const {
432 return needs_native_bridge_;
433 }
434
Elliott Hughes79082e32011-08-25 12:07:32 -0700435 void* FindSymbol(const std::string& symbol_name) {
436 return dlsym(handle_, symbol_name.c_str());
437 }
438
Yong WU355383f2014-07-24 21:32:15 +0800439 void* FindSymbolWithNativeBridge(const std::string& symbol_name, mirror::ArtMethod* m)
440 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
441 CHECK(NeedsNativeBridge());
442
443 uint32_t len = 0;
444 const char* shorty = nullptr;
445 if (m != nullptr) {
446 shorty = m->GetShorty(&len);
447 }
448 return NativeBridge::GetTrampoline(handle_, symbol_name.c_str(), shorty, len);
449 }
450
Mathieu Chartier83c8ee02014-01-28 14:50:23 -0800451 void VisitRoots(RootCallback* visitor, void* arg) {
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -0700452 if (!class_loader_.IsNull()) {
453 class_loader_.VisitRoot(visitor, arg, 0, kRootVMInternal);
Mathieu Chartier8f4be932014-01-28 15:25:19 -0800454 }
455 }
456
Elliott Hughes79082e32011-08-25 12:07:32 -0700457 private:
458 enum JNI_OnLoadState {
459 kPending,
460 kFailed,
461 kOkay,
462 };
463
464 // Path to library "/system/lib/libjni.so".
465 std::string path_;
466
467 // The void* returned by dlopen(3).
468 void* handle_;
469
Yong WU355383f2014-07-24 21:32:15 +0800470 // True if a native bridge is required.
471 bool needs_native_bridge_;
472
Elliott Hughes79082e32011-08-25 12:07:32 -0700473 // The ClassLoader this library is associated with.
Hiroshi Yamauchi94f7b492014-07-22 18:08:23 -0700474 GcRoot<mirror::Object> class_loader_;
Elliott Hughes79082e32011-08-25 12:07:32 -0700475
476 // Guards remaining items.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700477 Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
Elliott Hughes79082e32011-08-25 12:07:32 -0700478 // Wait for JNI_OnLoad in other thread.
Ian Rogersc604d732012-10-14 16:09:54 -0700479 ConditionVariable jni_on_load_cond_ GUARDED_BY(jni_on_load_lock_);
Elliott Hughes79082e32011-08-25 12:07:32 -0700480 // Recursive invocation guard.
Elliott Hughesf8349362012-06-18 15:00:06 -0700481 uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_);
Elliott Hughes79082e32011-08-25 12:07:32 -0700482 // Result of earlier JNI_OnLoad call.
Elliott Hughesf8349362012-06-18 15:00:06 -0700483 JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_);
Elliott Hughes79082e32011-08-25 12:07:32 -0700484};
485
Elliott Hughes79082e32011-08-25 12:07:32 -0700486// This exists mainly to keep implementation details out of the header file.
487class Libraries {
488 public:
489 Libraries() {
490 }
491
492 ~Libraries() {
Elliott Hughesc31664f2011-09-29 15:58:28 -0700493 STLDeleteValues(&libraries_);
Elliott Hughes79082e32011-08-25 12:07:32 -0700494 }
495
Elliott Hughesae80b492012-04-24 10:43:17 -0700496 void Dump(std::ostream& os) const {
497 bool first = true;
Mathieu Chartier02e25112013-08-14 16:14:24 -0700498 for (const auto& library : libraries_) {
Elliott Hughesae80b492012-04-24 10:43:17 -0700499 if (!first) {
500 os << ' ';
501 }
502 first = false;
Mathieu Chartier02e25112013-08-14 16:14:24 -0700503 os << library.first;
Elliott Hughesae80b492012-04-24 10:43:17 -0700504 }
505 }
506
507 size_t size() const {
508 return libraries_.size();
509 }
510
Elliott Hughes79082e32011-08-25 12:07:32 -0700511 SharedLibrary* Get(const std::string& path) {
Mathieu Chartier02e25112013-08-14 16:14:24 -0700512 auto it = libraries_.find(path);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800513 return (it == libraries_.end()) ? nullptr : it->second;
Elliott Hughes79082e32011-08-25 12:07:32 -0700514 }
515
516 void Put(const std::string& path, SharedLibrary* library) {
Elliott Hughesa0e18062012-04-13 15:59:59 -0700517 libraries_.Put(path, library);
Elliott Hughes79082e32011-08-25 12:07:32 -0700518 }
519
520 // See section 11.3 "Linking Native Methods" of the JNI spec.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800521 void* FindNativeMethod(mirror::ArtMethod* m, std::string& detail)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700522 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes79082e32011-08-25 12:07:32 -0700523 std::string jni_short_name(JniShortName(m));
524 std::string jni_long_name(JniLongName(m));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800525 const mirror::ClassLoader* declaring_class_loader = m->GetDeclaringClass()->GetClassLoader();
Mathieu Chartier02e25112013-08-14 16:14:24 -0700526 for (const auto& lib : libraries_) {
527 SharedLibrary* library = lib.second;
Elliott Hughes79082e32011-08-25 12:07:32 -0700528 if (library->GetClassLoader() != declaring_class_loader) {
529 // We only search libraries loaded by the appropriate ClassLoader.
530 continue;
531 }
532 // Try the short name then the long name...
Yong WU355383f2014-07-24 21:32:15 +0800533 void* fn = nullptr;
534 if (UNLIKELY(library->NeedsNativeBridge())) {
535 fn = library->FindSymbolWithNativeBridge(jni_short_name, m);
536 if (fn == nullptr) {
537 fn = library->FindSymbolWithNativeBridge(jni_long_name, m);
538 }
539 } else {
540 fn = library->FindSymbol(jni_short_name);
541 if (fn == nullptr) {
542 fn = library->FindSymbol(jni_long_name);
543 }
Elliott Hughes79082e32011-08-25 12:07:32 -0700544 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800545 if (fn != nullptr) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800546 VLOG(jni) << "[Found native code for " << PrettyMethod(m)
547 << " in \"" << library->GetPath() << "\"]";
Elliott Hughes79082e32011-08-25 12:07:32 -0700548 return fn;
549 }
550 }
Elliott Hughes79082e32011-08-25 12:07:32 -0700551 detail += "No implementation found for ";
Elliott Hughesa2501992011-08-26 19:39:54 -0700552 detail += PrettyMethod(m);
Brian Carlstrom92827a52011-10-10 15:50:01 -0700553 detail += " (tried " + jni_short_name + " and " + jni_long_name + ")";
Elliott Hughes79082e32011-08-25 12:07:32 -0700554 LOG(ERROR) << detail;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800555 return nullptr;
Elliott Hughes79082e32011-08-25 12:07:32 -0700556 }
557
Mathieu Chartier83c8ee02014-01-28 14:50:23 -0800558 void VisitRoots(RootCallback* callback, void* arg) {
Mathieu Chartier8f4be932014-01-28 15:25:19 -0800559 for (auto& lib_pair : libraries_) {
Mathieu Chartier83c8ee02014-01-28 14:50:23 -0800560 lib_pair.second->VisitRoots(callback, arg);
Mathieu Chartier8f4be932014-01-28 15:25:19 -0800561 }
562 }
563
Elliott Hughes79082e32011-08-25 12:07:32 -0700564 private:
Elliott Hughesa0e18062012-04-13 15:59:59 -0700565 SafeMap<std::string, SharedLibrary*> libraries_;
Elliott Hughes79082e32011-08-25 12:07:32 -0700566};
567
Ian Rogers2d10b202014-05-12 19:15:18 -0700568#define CHECK_NON_NULL_ARGUMENT(value) \
569 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700570
Ian Rogers2d10b202014-05-12 19:15:18 -0700571#define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
572 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
573
574#define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
575 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
576
577#define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
578 CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
579
580#define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800581 if (UNLIKELY(value == nullptr)) { \
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700582 JniAbortF(name, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700583 return return_val; \
Ian Rogersbc939662013-08-15 10:26:54 -0700584 }
585
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700586#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800587 if (UNLIKELY(length != 0 && value == nullptr)) { \
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700588 JniAbortF(__FUNCTION__, #value " == null"); \
Ian Rogers2d10b202014-05-12 19:15:18 -0700589 return; \
Ian Rogers4ffdc6b2013-08-21 16:55:13 -0700590 }
591
Elliott Hughescdf53122011-08-19 15:46:09 -0700592class JNI {
593 public:
Ian Rogers25e8b912012-09-07 11:31:36 -0700594 static jint GetVersion(JNIEnv*) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700595 return JNI_VERSION_1_6;
596 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700597
Ian Rogers25e8b912012-09-07 11:31:36 -0700598 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700599 LOG(WARNING) << "JNI DefineClass is not supported";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800600 return nullptr;
Elliott Hughesf2682d52011-08-15 16:37:04 -0700601 }
602
Elliott Hughescdf53122011-08-19 15:46:09 -0700603 static jclass FindClass(JNIEnv* env, const char* name) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700604 CHECK_NON_NULL_ARGUMENT(name);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700605 Runtime* runtime = Runtime::Current();
606 ClassLinker* class_linker = runtime->GetClassLinker();
Elliott Hughescdf53122011-08-19 15:46:09 -0700607 std::string descriptor(NormalizeJniClassDescriptor(name));
Brian Carlstromea46f952013-07-30 01:26:50 -0700608 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800609 mirror::Class* c = nullptr;
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700610 if (runtime->IsStarted()) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700611 StackHandleScope<1> hs(soa.Self());
612 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
Ian Rogers98379392014-02-24 16:53:16 -0800613 c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700614 } else {
Ian Rogers98379392014-02-24 16:53:16 -0800615 c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
Elliott Hughes5fe594f2011-09-08 12:33:17 -0700616 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700617 return soa.AddLocalReference<jclass>(c);
Ian Rogers4dd71f12011-08-16 14:16:02 -0700618 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700619
Ian Rogers62f05122014-03-21 11:21:29 -0700620 static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700621 CHECK_NON_NULL_ARGUMENT(jlr_method);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700622 ScopedObjectAccess soa(env);
Ian Rogers62f05122014-03-21 11:21:29 -0700623 return soa.EncodeMethod(mirror::ArtMethod::FromReflectedMethod(soa, jlr_method));
Elliott Hughesf2682d52011-08-15 16:37:04 -0700624 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700625
Ian Rogers62f05122014-03-21 11:21:29 -0700626 static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700627 CHECK_NON_NULL_ARGUMENT(jlr_field);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700628 ScopedObjectAccess soa(env);
Ian Rogers62f05122014-03-21 11:21:29 -0700629 return soa.EncodeField(mirror::ArtField::FromReflectedField(soa, jlr_field));
Elliott Hughescdf53122011-08-19 15:46:09 -0700630 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700631
Elliott Hughescdf53122011-08-19 15:46:09 -0700632 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700633 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700634 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800635 mirror::ArtMethod* m = soa.DecodeMethod(mid);
636 CHECK(!kMovingMethods);
Brian Carlstromea46f952013-07-30 01:26:50 -0700637 jobject art_method = soa.AddLocalReference<jobject>(m);
Sebastien Hertzd3333762014-06-26 14:45:07 +0200638 jobject reflect_method;
639 if (m->IsConstructor()) {
640 reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Constructor);
641 } else {
642 reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Method);
643 }
Brian Carlstromea46f952013-07-30 01:26:50 -0700644 if (env->ExceptionCheck()) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800645 return nullptr;
Brian Carlstromea46f952013-07-30 01:26:50 -0700646 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800647 SetObjectField(env, reflect_method,
648 WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod, art_method);
Brian Carlstromea46f952013-07-30 01:26:50 -0700649 return reflect_method;
Elliott Hughescdf53122011-08-19 15:46:09 -0700650 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700651
Elliott Hughescdf53122011-08-19 15:46:09 -0700652 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700653 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700654 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800655 mirror::ArtField* f = soa.DecodeField(fid);
Brian Carlstromea46f952013-07-30 01:26:50 -0700656 jobject art_field = soa.AddLocalReference<jobject>(f);
657 jobject reflect_field = env->AllocObject(WellKnownClasses::java_lang_reflect_Field);
658 if (env->ExceptionCheck()) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800659 return nullptr;
Brian Carlstromea46f952013-07-30 01:26:50 -0700660 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800661 SetObjectField(env, reflect_field,
662 WellKnownClasses::java_lang_reflect_Field_artField, art_field);
Brian Carlstromea46f952013-07-30 01:26:50 -0700663 return reflect_field;
Elliott Hughescdf53122011-08-19 15:46:09 -0700664 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700665
Elliott Hughes37f7a402011-08-22 18:56:01 -0700666 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700667 CHECK_NON_NULL_ARGUMENT(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700668 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800669 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700670 return soa.AddLocalReference<jclass>(o->GetClass());
Elliott Hughes37f7a402011-08-22 18:56:01 -0700671 }
672
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700673 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700674 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700675 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800676 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700677 return soa.AddLocalReference<jclass>(c->GetSuperClass());
Elliott Hughescdf53122011-08-19 15:46:09 -0700678 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700679
Narayan Kamath1268b742014-07-11 19:15:11 +0100680 // Note: java_class1 should be safely castable to java_class2, and
681 // not the other way around.
Elliott Hughes37f7a402011-08-22 18:56:01 -0700682 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700683 CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
684 CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700685 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800686 mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
687 mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
Narayan Kamath1268b742014-07-11 19:15:11 +0100688 return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
Elliott Hughescdf53122011-08-19 15:46:09 -0700689 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700690
Elliott Hughese84278b2012-03-22 10:06:53 -0700691 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700692 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800693 if (jobj == nullptr) {
Brian Carlstrom5d40f182011-09-26 22:29:18 -0700694 // Note: JNI is different from regular Java instanceof in this respect
Elliott Hughes37f7a402011-08-22 18:56:01 -0700695 return JNI_TRUE;
696 } else {
Brian Carlstromea46f952013-07-30 01:26:50 -0700697 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800698 mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
699 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughese84278b2012-03-22 10:06:53 -0700700 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700701 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700702 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700703
Elliott Hughes37f7a402011-08-22 18:56:01 -0700704 static jint Throw(JNIEnv* env, jthrowable java_exception) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700705 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800706 mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
707 if (exception == nullptr) {
Elliott Hughes37f7a402011-08-22 18:56:01 -0700708 return JNI_ERR;
709 }
Ian Rogers62d6c772013-02-27 08:32:07 -0800710 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
711 soa.Self()->SetException(throw_location, exception);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700712 return JNI_OK;
713 }
714
Elliott Hughese5b0dc82011-08-23 09:59:02 -0700715 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700716 CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800717 return ThrowNewException(env, c, msg, nullptr);
Elliott Hughes37f7a402011-08-22 18:56:01 -0700718 }
719
720 static jboolean ExceptionCheck(JNIEnv* env) {
Ian Rogers120f1c72012-09-28 17:17:10 -0700721 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
Elliott Hughes37f7a402011-08-22 18:56:01 -0700722 }
723
724 static void ExceptionClear(JNIEnv* env) {
Serguei Katkova309d762014-05-26 11:23:39 +0700725 ScopedObjectAccess soa(env);
726 soa.Self()->ClearException();
Elliott Hughes37f7a402011-08-22 18:56:01 -0700727 }
728
729 static void ExceptionDescribe(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700730 ScopedObjectAccess soa(env);
Elliott Hughes72025e52011-08-23 17:50:30 -0700731
Alexei Zavjalov3a1444c2014-06-25 16:04:55 +0700732 // If we have no exception to describe, pass through.
733 if (!soa.Self()->GetException(nullptr)) {
734 return;
735 }
736
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700737 StackHandleScope<3> hs(soa.Self());
738 // TODO: Use nullptr instead of null handles?
739 auto old_throw_this_object(hs.NewHandle<mirror::Object>(nullptr));
740 auto old_throw_method(hs.NewHandle<mirror::ArtMethod>(nullptr));
741 auto old_exception(hs.NewHandle<mirror::Throwable>(nullptr));
Ian Rogers62d6c772013-02-27 08:32:07 -0800742 uint32_t old_throw_dex_pc;
Sebastien Hertz9f102032014-05-23 08:59:42 +0200743 bool old_is_exception_reported;
Ian Rogers62d6c772013-02-27 08:32:07 -0800744 {
745 ThrowLocation old_throw_location;
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800746 mirror::Throwable* old_exception_obj = soa.Self()->GetException(&old_throw_location);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700747 old_throw_this_object.Assign(old_throw_location.GetThis());
748 old_throw_method.Assign(old_throw_location.GetMethod());
749 old_exception.Assign(old_exception_obj);
Ian Rogers62d6c772013-02-27 08:32:07 -0800750 old_throw_dex_pc = old_throw_location.GetDexPc();
Sebastien Hertz9f102032014-05-23 08:59:42 +0200751 old_is_exception_reported = soa.Self()->IsExceptionReportedToInstrumentation();
Ian Rogers62d6c772013-02-27 08:32:07 -0800752 soa.Self()->ClearException();
753 }
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800754 ScopedLocalRef<jthrowable> exception(env,
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700755 soa.AddLocalReference<jthrowable>(old_exception.Get()));
Elliott Hughes72025e52011-08-23 17:50:30 -0700756 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
757 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800758 if (mid == nullptr) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700759 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700760 << PrettyTypeOf(old_exception.Get());
Elliott Hughes72025e52011-08-23 17:50:30 -0700761 } else {
762 env->CallVoidMethod(exception.get(), mid);
Ian Rogers62d6c772013-02-27 08:32:07 -0800763 if (soa.Self()->IsExceptionPending()) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800764 LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException(nullptr))
Elliott Hughes72025e52011-08-23 17:50:30 -0700765 << " thrown while calling printStackTrace";
Ian Rogers62d6c772013-02-27 08:32:07 -0800766 soa.Self()->ClearException();
Elliott Hughes72025e52011-08-23 17:50:30 -0700767 }
768 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700769 ThrowLocation gc_safe_throw_location(old_throw_this_object.Get(), old_throw_method.Get(),
Ian Rogers62d6c772013-02-27 08:32:07 -0800770 old_throw_dex_pc);
Elliott Hughes72025e52011-08-23 17:50:30 -0700771
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700772 soa.Self()->SetException(gc_safe_throw_location, old_exception.Get());
Sebastien Hertz9f102032014-05-23 08:59:42 +0200773 soa.Self()->SetExceptionReportedToInstrumentation(old_is_exception_reported);
Elliott Hughescdf53122011-08-19 15:46:09 -0700774 }
Carl Shapiroea4dca82011-08-01 13:45:38 -0700775
Elliott Hughescdf53122011-08-19 15:46:09 -0700776 static jthrowable ExceptionOccurred(JNIEnv* env) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700777 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800778 mirror::Object* exception = soa.Self()->GetException(nullptr);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700779 return soa.AddLocalReference<jthrowable>(exception);
Elliott Hughescdf53122011-08-19 15:46:09 -0700780 }
781
Ian Rogers25e8b912012-09-07 11:31:36 -0700782 static void FatalError(JNIEnv*, const char* msg) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700783 LOG(FATAL) << "JNI FatalError called: " << msg;
784 }
785
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700786 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700787 // TODO: SOA may not be necessary but I do it to please lock annotations.
788 ScopedObjectAccess soa(env);
789 if (EnsureLocalCapacity(soa, capacity, "PushLocalFrame") != JNI_OK) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700790 return JNI_ERR;
791 }
Ian Rogersef28b142012-11-30 14:22:18 -0800792 static_cast<JNIEnvExt*>(env)->PushFrame(capacity);
Elliott Hughescdf53122011-08-19 15:46:09 -0700793 return JNI_OK;
794 }
795
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700796 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700797 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800798 mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700799 soa.Env()->PopFrame();
800 return soa.AddLocalReference<jobject>(survivor);
Elliott Hughescdf53122011-08-19 15:46:09 -0700801 }
802
Elliott Hughes2ced6a52011-10-16 18:44:48 -0700803 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700804 // TODO: SOA may not be necessary but I do it to please lock annotations.
805 ScopedObjectAccess soa(env);
806 return EnsureLocalCapacity(soa, desired_capacity, "EnsureLocalCapacity");
Elliott Hughes72025e52011-08-23 17:50:30 -0700807 }
808
Elliott Hughescdf53122011-08-19 15:46:09 -0700809 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700810 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800811 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
Mathieu Chartiere8c48db2013-12-19 14:59:00 -0800812 // Check for null after decoding the object to handle cleared weak globals.
813 if (decoded_obj == nullptr) {
814 return nullptr;
815 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700816 JavaVMExt* vm = soa.Vm();
Elliott Hughescdf53122011-08-19 15:46:09 -0700817 IndirectReferenceTable& globals = vm->globals;
Ian Rogersb8a0b942013-08-20 18:09:52 -0700818 WriterMutexLock mu(soa.Self(), vm->globals_lock);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700819 IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700820 return reinterpret_cast<jobject>(ref);
821 }
822
823 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800824 if (obj == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700825 return;
826 }
Ian Rogersef28b142012-11-30 14:22:18 -0800827 JavaVMExt* vm = reinterpret_cast<JNIEnvExt*>(env)->vm;
Elliott Hughescdf53122011-08-19 15:46:09 -0700828 IndirectReferenceTable& globals = vm->globals;
Ian Rogersef28b142012-11-30 14:22:18 -0800829 Thread* self = reinterpret_cast<JNIEnvExt*>(env)->self;
Ian Rogersb8a0b942013-08-20 18:09:52 -0700830 WriterMutexLock mu(self, vm->globals_lock);
Elliott Hughescdf53122011-08-19 15:46:09 -0700831
832 if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
833 LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
834 << "failed to find entry";
835 }
836 }
837
838 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700839 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800840 return AddWeakGlobalReference(soa, soa.Decode<mirror::Object*>(obj));
Elliott Hughescdf53122011-08-19 15:46:09 -0700841 }
842
843 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
Mathieu Chartierc11d9b82013-09-19 10:01:59 -0700844 if (obj != nullptr) {
845 ScopedObjectAccess soa(env);
846 soa.Vm()->DeleteWeakGlobalRef(soa.Self(), obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700847 }
848 }
849
850 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
Ian Rogers25e8b912012-09-07 11:31:36 -0700851 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800852 mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
Mathieu Chartiere8c48db2013-12-19 14:59:00 -0800853 // Check for null after decoding the object to handle cleared weak globals.
854 if (decoded_obj == nullptr) {
855 return nullptr;
856 }
857 return soa.AddLocalReference<jobject>(decoded_obj);
Elliott Hughescdf53122011-08-19 15:46:09 -0700858 }
859
860 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800861 if (obj == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700862 return;
863 }
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +0700864 ScopedObjectAccess soa(env);
Ian Rogersef28b142012-11-30 14:22:18 -0800865 IndirectReferenceTable& locals = reinterpret_cast<JNIEnvExt*>(env)->locals;
Elliott Hughescdf53122011-08-19 15:46:09 -0700866
Ian Rogersef28b142012-11-30 14:22:18 -0800867 uint32_t cookie = reinterpret_cast<JNIEnvExt*>(env)->local_ref_cookie;
Elliott Hughescdf53122011-08-19 15:46:09 -0700868 if (!locals.Remove(cookie, obj)) {
869 // Attempting to delete a local reference that is not in the
870 // topmost local reference frame is a no-op. DeleteLocalRef returns
871 // void and doesn't throw any exceptions, but we should probably
872 // complain about it so the user will notice that things aren't
873 // going quite the way they expect.
874 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
875 << "failed to find entry";
876 }
877 }
878
879 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700880 if (obj1 == obj2) {
881 return JNI_TRUE;
882 } else {
883 ScopedObjectAccess soa(env);
Brian Carlstrom491ca9e2014-03-02 18:24:38 -0800884 return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
885 ? JNI_TRUE : JNI_FALSE;
Brian Carlstromea46f952013-07-30 01:26:50 -0700886 }
Elliott Hughescdf53122011-08-19 15:46:09 -0700887 }
888
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700889 static jobject AllocObject(JNIEnv* env, jclass java_class) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700890 CHECK_NON_NULL_ARGUMENT(java_class);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700891 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800892 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800893 if (c == nullptr) {
894 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700895 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700896 return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
Elliott Hughescdf53122011-08-19 15:46:09 -0700897 }
898
Ian Rogersbc939662013-08-15 10:26:54 -0700899 static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -0700900 va_list args;
Elliott Hughes72025e52011-08-23 17:50:30 -0700901 va_start(args, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700902 CHECK_NON_NULL_ARGUMENT(java_class);
903 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogersbc939662013-08-15 10:26:54 -0700904 jobject result = NewObjectV(env, java_class, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -0700905 va_end(args);
906 return result;
907 }
908
Elliott Hughes72025e52011-08-23 17:50:30 -0700909 static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700910 CHECK_NON_NULL_ARGUMENT(java_class);
911 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700912 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800913 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800914 if (c == nullptr) {
915 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700916 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800917 mirror::Object* result = c->AllocObject(soa.Self());
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800918 if (result == nullptr) {
919 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700920 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700921 jobject local_result = soa.AddLocalReference<jobject>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700922 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800923 if (soa.Self()->IsExceptionPending()) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800924 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700925 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800926 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700927 }
928
Elliott Hughes72025e52011-08-23 17:50:30 -0700929 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700930 CHECK_NON_NULL_ARGUMENT(java_class);
931 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700932 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800933 mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800934 if (c == nullptr) {
935 return nullptr;
Elliott Hughes885c3bd2011-08-22 16:59:20 -0700936 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800937 mirror::Object* result = c->AllocObject(soa.Self());
938 if (result == nullptr) {
939 return nullptr;
Elliott Hughes30646832011-10-13 16:59:46 -0700940 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700941 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
Elliott Hughes72025e52011-08-23 17:50:30 -0700942 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800943 if (soa.Self()->IsExceptionPending()) {
944 return nullptr;
Ian Rogers5d4bdc22011-11-02 22:15:43 -0700945 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -0800946 return local_result;
Elliott Hughescdf53122011-08-19 15:46:09 -0700947 }
948
Ian Rogersbc939662013-08-15 10:26:54 -0700949 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700950 CHECK_NON_NULL_ARGUMENT(java_class);
951 CHECK_NON_NULL_ARGUMENT(name);
952 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700953 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700954 return FindMethodID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -0700955 }
956
Ian Rogersbc939662013-08-15 10:26:54 -0700957 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
958 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700959 CHECK_NON_NULL_ARGUMENT(java_class);
960 CHECK_NON_NULL_ARGUMENT(name);
961 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700962 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -0700963 return FindMethodID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -0700964 }
965
Elliott Hughes72025e52011-08-23 17:50:30 -0700966 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700967 va_list ap;
968 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700969 CHECK_NON_NULL_ARGUMENT(obj);
970 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700971 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700972 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -0700973 va_end(ap);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700974 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700975 }
976
Elliott Hughes72025e52011-08-23 17:50:30 -0700977 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700978 CHECK_NON_NULL_ARGUMENT(obj);
979 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700980 ScopedObjectAccess soa(env);
981 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
982 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700983 }
984
Elliott Hughes72025e52011-08-23 17:50:30 -0700985 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -0700986 CHECK_NON_NULL_ARGUMENT(obj);
987 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700988 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -0700989 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
990 args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700991 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -0700992 }
993
Elliott Hughes72025e52011-08-23 17:50:30 -0700994 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -0700995 va_list ap;
996 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -0700997 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
998 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -0700999 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001000 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001001 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001002 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001003 }
1004
Elliott Hughes72025e52011-08-23 17:50:30 -07001005 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001006 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1007 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001008 ScopedObjectAccess soa(env);
1009 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001010 }
1011
Elliott Hughes72025e52011-08-23 17:50:30 -07001012 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001013 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1014 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001015 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001016 return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1017 args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001018 }
1019
Elliott Hughes72025e52011-08-23 17:50:30 -07001020 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001021 va_list ap;
1022 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001023 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1024 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001025 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001026 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001027 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001028 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001029 }
1030
Elliott Hughes72025e52011-08-23 17:50:30 -07001031 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001032 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1033 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001034 ScopedObjectAccess soa(env);
1035 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001036 }
1037
Elliott Hughes72025e52011-08-23 17:50:30 -07001038 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001039 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1040 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001041 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001042 return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1043 args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001044 }
1045
Elliott Hughes72025e52011-08-23 17:50:30 -07001046 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001047 va_list ap;
1048 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001049 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1050 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001051 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001052 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001053 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001054 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001055 }
1056
Elliott Hughes72025e52011-08-23 17:50:30 -07001057 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001058 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1059 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001060 ScopedObjectAccess soa(env);
1061 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001062 }
1063
Elliott Hughes72025e52011-08-23 17:50:30 -07001064 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001065 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1066 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001067 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001068 return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1069 args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001070 }
1071
Elliott Hughes72025e52011-08-23 17:50:30 -07001072 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001073 va_list ap;
1074 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001075 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1076 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001077 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001078 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001079 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001080 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001081 }
1082
Elliott Hughes72025e52011-08-23 17:50:30 -07001083 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001084 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1085 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001086 ScopedObjectAccess soa(env);
1087 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001088 }
1089
Elliott Hughes72025e52011-08-23 17:50:30 -07001090 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001091 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1092 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001093 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001094 return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1095 args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001096 }
1097
Elliott Hughes72025e52011-08-23 17:50:30 -07001098 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001099 va_list ap;
1100 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001101 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1102 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001103 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001104 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001105 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001106 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001107 }
1108
Elliott Hughes72025e52011-08-23 17:50:30 -07001109 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001110 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1111 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001112 ScopedObjectAccess soa(env);
1113 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001114 }
1115
Elliott Hughes72025e52011-08-23 17:50:30 -07001116 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001117 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1118 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001119 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001120 return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1121 args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001122 }
1123
Elliott Hughes72025e52011-08-23 17:50:30 -07001124 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001125 va_list ap;
1126 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001127 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1128 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001129 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001130 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001131 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001132 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001133 }
1134
Elliott Hughes72025e52011-08-23 17:50:30 -07001135 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001136 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1137 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001138 ScopedObjectAccess soa(env);
1139 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001140 }
1141
Elliott Hughes72025e52011-08-23 17:50:30 -07001142 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001143 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1144 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001145 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001146 return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1147 args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001148 }
1149
Elliott Hughes72025e52011-08-23 17:50:30 -07001150 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001151 va_list ap;
1152 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001153 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1154 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001155 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001156 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001157 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001158 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001159 }
1160
Elliott Hughes72025e52011-08-23 17:50:30 -07001161 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001162 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1163 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001164 ScopedObjectAccess soa(env);
1165 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001166 }
1167
Elliott Hughes72025e52011-08-23 17:50:30 -07001168 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001169 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1170 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001171 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001172 return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1173 args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001174 }
1175
Elliott Hughes72025e52011-08-23 17:50:30 -07001176 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001177 va_list ap;
1178 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001179 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1180 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001181 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001182 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
Elliott Hughes72025e52011-08-23 17:50:30 -07001183 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001184 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001185 }
1186
Elliott Hughes72025e52011-08-23 17:50:30 -07001187 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001188 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1189 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001190 ScopedObjectAccess soa(env);
1191 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001192 }
1193
Elliott Hughes72025e52011-08-23 17:50:30 -07001194 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001195 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1196 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001197 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001198 return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1199 args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001200 }
1201
Elliott Hughes72025e52011-08-23 17:50:30 -07001202 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
Elliott Hughes72025e52011-08-23 17:50:30 -07001203 va_list ap;
1204 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001205 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1206 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001207 ScopedObjectAccess soa(env);
Ian Rogers1b09b092012-08-20 15:35:52 -07001208 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
Elliott Hughes72025e52011-08-23 17:50:30 -07001209 va_end(ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001210 }
1211
Elliott Hughes72025e52011-08-23 17:50:30 -07001212 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001213 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1214 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001215 ScopedObjectAccess soa(env);
1216 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001217 }
1218
Elliott Hughes72025e52011-08-23 17:50:30 -07001219 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001220 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1221 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001222 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001223 InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001224 }
1225
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001226 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001227 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001228 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001229 CHECK_NON_NULL_ARGUMENT(obj);
1230 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001231 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001232 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1233 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001234 va_end(ap);
1235 return local_result;
1236 }
1237
Ian Rogersbc939662013-08-15 10:26:54 -07001238 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1239 va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001240 CHECK_NON_NULL_ARGUMENT(obj);
1241 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001242 ScopedObjectAccess soa(env);
1243 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
1244 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001245 }
1246
Ian Rogersbc939662013-08-15 10:26:54 -07001247 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1248 jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001249 CHECK_NON_NULL_ARGUMENT(obj);
1250 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001251 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001252 JValue result(InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001253 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001254 }
1255
Ian Rogersbc939662013-08-15 10:26:54 -07001256 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1257 ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001258 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001259 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001260 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1261 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001262 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001263 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001264 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001265 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001266 }
1267
Ian Rogersbc939662013-08-15 10:26:54 -07001268 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1269 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001270 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1271 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001272 ScopedObjectAccess soa(env);
1273 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001274 }
1275
Ian Rogersbc939662013-08-15 10:26:54 -07001276 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1277 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001278 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1279 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001280 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001281 return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001282 }
1283
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001284 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001285 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001286 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001287 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1288 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001289 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001290 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001291 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001292 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001293 }
1294
Ian Rogersbc939662013-08-15 10:26:54 -07001295 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1296 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001297 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1298 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001299 ScopedObjectAccess soa(env);
1300 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001301 }
1302
Ian Rogersbc939662013-08-15 10:26:54 -07001303 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1304 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001305 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1306 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001307 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001308 return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001309 }
1310
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001311 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001312 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001313 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001314 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1315 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogersbc939662013-08-15 10:26:54 -07001316 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001317 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001318 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001319 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001320 }
1321
Ian Rogersbc939662013-08-15 10:26:54 -07001322 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1323 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001324 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1325 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001326 ScopedObjectAccess soa(env);
1327 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001328 }
1329
Ian Rogersbc939662013-08-15 10:26:54 -07001330 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1331 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001332 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1333 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001334 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001335 return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001336 }
1337
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001338 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001339 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001340 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001341 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1342 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001343 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001344 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001345 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001346 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001347 }
1348
Ian Rogersbc939662013-08-15 10:26:54 -07001349 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1350 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001351 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1352 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001353 ScopedObjectAccess soa(env);
1354 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001355 }
1356
Ian Rogersbc939662013-08-15 10:26:54 -07001357 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1358 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001359 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1360 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001361 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001362 return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001363 }
1364
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001365 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001366 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001367 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001368 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1369 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001370 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001371 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001372 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001373 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001374 }
1375
Ian Rogersbc939662013-08-15 10:26:54 -07001376 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1377 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001378 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1379 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001380 ScopedObjectAccess soa(env);
1381 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001382 }
1383
Ian Rogersbc939662013-08-15 10:26:54 -07001384 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1385 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001386 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1387 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001388 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001389 return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001390 }
1391
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001392 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001393 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001394 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001395 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1396 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001397 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001398 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001399 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001400 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001401 }
1402
Ian Rogersbc939662013-08-15 10:26:54 -07001403 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1404 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001405 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1406 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001407 ScopedObjectAccess soa(env);
1408 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001409 }
1410
Ian Rogersbc939662013-08-15 10:26:54 -07001411 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1412 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001413 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1414 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001415 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001416 return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001417 }
1418
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001419 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001420 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001421 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001422 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1423 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001424 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001425 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001426 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001427 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001428 }
1429
Ian Rogersbc939662013-08-15 10:26:54 -07001430 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1431 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001432 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1433 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001434 ScopedObjectAccess soa(env);
1435 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001436 }
1437
Ian Rogersbc939662013-08-15 10:26:54 -07001438 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1439 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001440 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1441 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001442 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001443 return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001444 }
1445
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001446 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001447 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001448 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001449 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1450 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001451 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001452 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001453 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001454 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001455 }
1456
Ian Rogersbc939662013-08-15 10:26:54 -07001457 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1458 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001459 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1460 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001461 ScopedObjectAccess soa(env);
1462 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001463 }
1464
Ian Rogersbc939662013-08-15 10:26:54 -07001465 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1466 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001467 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1468 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001469 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001470 return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001471 }
1472
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001473 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001474 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001475 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001476 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1477 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001478 ScopedObjectAccess soa(env);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001479 InvokeWithVarArgs(soa, obj, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001480 va_end(ap);
1481 }
1482
Brian Carlstromea46f952013-07-30 01:26:50 -07001483 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1484 va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001485 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1486 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001487 ScopedObjectAccess soa(env);
1488 InvokeWithVarArgs(soa, obj, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001489 }
1490
Ian Rogersbc939662013-08-15 10:26:54 -07001491 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1492 jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001493 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1494 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001495 ScopedObjectAccess soa(env);
Ian Rogers53b8b092014-03-13 23:45:53 -07001496 InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001497 }
1498
Ian Rogersbc939662013-08-15 10:26:54 -07001499 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001500 CHECK_NON_NULL_ARGUMENT(java_class);
1501 CHECK_NON_NULL_ARGUMENT(name);
1502 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001503 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001504 return FindFieldID(soa, java_class, name, sig, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07001505 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001506
Ian Rogersbc939662013-08-15 10:26:54 -07001507 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1508 const char* sig) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001509 CHECK_NON_NULL_ARGUMENT(java_class);
1510 CHECK_NON_NULL_ARGUMENT(name);
1511 CHECK_NON_NULL_ARGUMENT(sig);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001512 ScopedObjectAccess soa(env);
Ian Rogersbc939662013-08-15 10:26:54 -07001513 return FindFieldID(soa, java_class, name, sig, true);
Elliott Hughescdf53122011-08-19 15:46:09 -07001514 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001515
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001516 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001517 CHECK_NON_NULL_ARGUMENT(obj);
1518 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001519 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001520 mirror::Object* o = soa.Decode<mirror::Object*>(obj);
1521 mirror::ArtField* f = soa.DecodeField(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001522 return soa.AddLocalReference<jobject>(f->GetObject(o));
Elliott Hughescdf53122011-08-19 15:46:09 -07001523 }
Carl Shapiroea4dca82011-08-01 13:45:38 -07001524
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001525 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001526 CHECK_NON_NULL_ARGUMENT(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001527 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001528 mirror::ArtField* f = soa.DecodeField(fid);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001529 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
Elliott Hughescdf53122011-08-19 15:46:09 -07001530 }
1531
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001532 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001533 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1534 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001535 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001536 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1537 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1538 mirror::ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001539 f->SetObject<false>(o, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001540 }
1541
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001542 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001543 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001544 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001545 mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1546 mirror::ArtField* f = soa.DecodeField(fid);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001547 f->SetObject<false>(f->GetDeclaringClass(), v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001548 }
1549
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001550#define GET_PRIMITIVE_FIELD(fn, instance) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001551 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1552 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001553 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001554 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1555 mirror::ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001556 return f->Get ##fn (o)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001557
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001558#define GET_STATIC_PRIMITIVE_FIELD(fn) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001559 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001560 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001561 mirror::ArtField* f = soa.DecodeField(fid); \
Ian Rogersbc939662013-08-15 10:26:54 -07001562 return f->Get ##fn (f->GetDeclaringClass())
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001563
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001564#define SET_PRIMITIVE_FIELD(fn, instance, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001565 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1566 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001567 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001568 mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1569 mirror::ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001570 f->Set ##fn <false>(o, value)
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001571
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001572#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
Ian Rogers2d10b202014-05-12 19:15:18 -07001573 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001574 ScopedObjectAccess soa(env); \
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001575 mirror::ArtField* f = soa.DecodeField(fid); \
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001576 f->Set ##fn <false>(f->GetDeclaringClass(), value)
Ian Rogers2fa6b2e2012-10-17 00:10:17 -07001577
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001578 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001579 GET_PRIMITIVE_FIELD(Boolean, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001580 }
1581
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001582 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001583 GET_PRIMITIVE_FIELD(Byte, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001584 }
1585
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001586 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001587 GET_PRIMITIVE_FIELD(Char, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001588 }
1589
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001590 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001591 GET_PRIMITIVE_FIELD(Short, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001592 }
1593
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001594 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001595 GET_PRIMITIVE_FIELD(Int, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001596 }
1597
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001598 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001599 GET_PRIMITIVE_FIELD(Long, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001600 }
1601
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001602 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001603 GET_PRIMITIVE_FIELD(Float, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001604 }
1605
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001606 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001607 GET_PRIMITIVE_FIELD(Double, obj);
Elliott Hughescdf53122011-08-19 15:46:09 -07001608 }
1609
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001610 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001611 GET_STATIC_PRIMITIVE_FIELD(Boolean);
Elliott Hughescdf53122011-08-19 15:46:09 -07001612 }
1613
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001614 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001615 GET_STATIC_PRIMITIVE_FIELD(Byte);
Elliott Hughescdf53122011-08-19 15:46:09 -07001616 }
1617
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001618 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001619 GET_STATIC_PRIMITIVE_FIELD(Char);
Elliott Hughescdf53122011-08-19 15:46:09 -07001620 }
1621
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001622 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001623 GET_STATIC_PRIMITIVE_FIELD(Short);
Elliott Hughescdf53122011-08-19 15:46:09 -07001624 }
1625
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001626 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001627 GET_STATIC_PRIMITIVE_FIELD(Int);
Elliott Hughescdf53122011-08-19 15:46:09 -07001628 }
1629
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001630 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001631 GET_STATIC_PRIMITIVE_FIELD(Long);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001632 }
1633
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001634 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001635 GET_STATIC_PRIMITIVE_FIELD(Float);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001636 }
1637
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001638 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
Ian Rogersbc939662013-08-15 10:26:54 -07001639 GET_STATIC_PRIMITIVE_FIELD(Double);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001640 }
1641
1642 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001643 SET_PRIMITIVE_FIELD(Boolean, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001644 }
1645
1646 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001647 SET_PRIMITIVE_FIELD(Byte, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001648 }
1649
1650 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001651 SET_PRIMITIVE_FIELD(Char, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001652 }
1653
1654 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001655 SET_PRIMITIVE_FIELD(Float, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001656 }
1657
1658 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001659 SET_PRIMITIVE_FIELD(Double, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001660 }
1661
1662 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001663 SET_PRIMITIVE_FIELD(Int, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001664 }
1665
1666 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001667 SET_PRIMITIVE_FIELD(Long, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001668 }
1669
1670 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001671 SET_PRIMITIVE_FIELD(Short, obj, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001672 }
1673
1674 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001675 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001676 }
1677
1678 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001679 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001680 }
1681
1682 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001683 SET_STATIC_PRIMITIVE_FIELD(Char, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001684 }
1685
1686 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001687 SET_STATIC_PRIMITIVE_FIELD(Float, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001688 }
1689
1690 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001691 SET_STATIC_PRIMITIVE_FIELD(Double, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001692 }
1693
1694 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001695 SET_STATIC_PRIMITIVE_FIELD(Int, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001696 }
1697
1698 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001699 SET_STATIC_PRIMITIVE_FIELD(Long, v);
Elliott Hughes885c3bd2011-08-22 16:59:20 -07001700 }
1701
1702 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
Ian Rogersbc939662013-08-15 10:26:54 -07001703 SET_STATIC_PRIMITIVE_FIELD(Short, v);
Elliott Hughescdf53122011-08-19 15:46:09 -07001704 }
1705
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001706 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001707 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001708 va_start(ap, mid);
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001709 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001710 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001711 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001712 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001713 va_end(ap);
1714 return local_result;
1715 }
1716
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001717 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001718 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001719 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001720 JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001721 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001722 }
1723
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001724 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001725 CHECK_NON_NULL_ARGUMENT(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001726 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001727 JValue result(InvokeWithJValues(soa, nullptr, mid, args));
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001728 return soa.AddLocalReference<jobject>(result.GetL());
Elliott Hughescdf53122011-08-19 15:46:09 -07001729 }
1730
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001731 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001732 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001733 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001734 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001735 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001736 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001737 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001738 return result.GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001739 }
1740
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001741 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001742 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001743 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001744 return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001745 }
1746
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001747 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001748 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001749 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001750 return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001751 }
1752
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001753 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001754 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001755 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001756 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001757 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001758 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001759 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001760 return result.GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001761 }
1762
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001763 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001764 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001765 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001766 return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001767 }
1768
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001769 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001770 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001771 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001772 return InvokeWithJValues(soa, nullptr, mid, args).GetB();
Elliott Hughescdf53122011-08-19 15:46:09 -07001773 }
1774
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001775 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001776 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001777 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001778 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001779 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001780 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001781 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001782 return result.GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001783 }
1784
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001785 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001786 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001787 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001788 return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001789 }
1790
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001791 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001792 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001793 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001794 return InvokeWithJValues(soa, nullptr, mid, args).GetC();
Elliott Hughescdf53122011-08-19 15:46:09 -07001795 }
1796
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001797 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001798 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001799 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001800 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001801 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001802 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001803 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001804 return result.GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001805 }
1806
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001807 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001808 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001809 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001810 return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001811 }
1812
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001813 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001814 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001815 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001816 return InvokeWithJValues(soa, nullptr, mid, args).GetS();
Elliott Hughescdf53122011-08-19 15:46:09 -07001817 }
1818
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001819 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001820 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001821 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001822 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001823 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001824 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001825 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001826 return result.GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001827 }
1828
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001829 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001830 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001831 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001832 return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001833 }
1834
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001835 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001836 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001837 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001838 return InvokeWithJValues(soa, nullptr, mid, args).GetI();
Elliott Hughescdf53122011-08-19 15:46:09 -07001839 }
1840
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001841 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001842 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001843 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001844 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001845 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001846 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001847 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001848 return result.GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001849 }
1850
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001851 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001852 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001853 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001854 return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001855 }
1856
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001857 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001858 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001859 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001860 return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
Elliott Hughescdf53122011-08-19 15:46:09 -07001861 }
1862
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001863 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001864 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001865 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001866 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001867 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001868 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001869 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001870 return result.GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001871 }
1872
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001873 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001874 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001875 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001876 return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001877 }
1878
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001879 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001880 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001881 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001882 return InvokeWithJValues(soa, nullptr, mid, args).GetF();
Elliott Hughescdf53122011-08-19 15:46:09 -07001883 }
1884
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001885 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001886 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001887 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001888 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001889 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001890 JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
Elliott Hughescdf53122011-08-19 15:46:09 -07001891 va_end(ap);
Elliott Hughesf24d3ce2012-04-11 17:43:37 -07001892 return result.GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001893 }
1894
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001895 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001896 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001897 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001898 return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001899 }
1900
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001901 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001902 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001903 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001904 return InvokeWithJValues(soa, nullptr, mid, args).GetD();
Elliott Hughescdf53122011-08-19 15:46:09 -07001905 }
1906
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001907 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
Elliott Hughescdf53122011-08-19 15:46:09 -07001908 va_list ap;
Elliott Hughes72025e52011-08-23 17:50:30 -07001909 va_start(ap, mid);
Ian Rogers2d10b202014-05-12 19:15:18 -07001910 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers25e8b912012-09-07 11:31:36 -07001911 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001912 InvokeWithVarArgs(soa, nullptr, mid, ap);
Elliott Hughescdf53122011-08-19 15:46:09 -07001913 va_end(ap);
1914 }
1915
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001916 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001917 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001918 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001919 InvokeWithVarArgs(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001920 }
1921
Elliott Hughes1bac54f2012-03-16 12:48:31 -07001922 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001923 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001924 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001925 InvokeWithJValues(soa, nullptr, mid, args);
Elliott Hughescdf53122011-08-19 15:46:09 -07001926 }
1927
Elliott Hughes814e4032011-08-23 12:07:56 -07001928 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
Ian Rogers1d99e452014-01-02 17:36:41 -08001929 if (UNLIKELY(char_count < 0)) {
1930 JniAbortF("NewString", "char_count < 0: %d", char_count);
1931 return nullptr;
1932 }
1933 if (UNLIKELY(chars == nullptr && char_count > 0)) {
1934 JniAbortF("NewString", "chars == null && char_count > 0");
1935 return nullptr;
Ian Rogersbc939662013-08-15 10:26:54 -07001936 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001937 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001938 mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001939 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001940 }
1941
1942 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001943 if (utf == nullptr) {
1944 return nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07001945 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001946 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001947 mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001948 return soa.AddLocalReference<jstring>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07001949 }
1950
Elliott Hughes814e4032011-08-23 12:07:56 -07001951 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001952 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001953 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001954 return soa.Decode<mirror::String*>(java_string)->GetLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001955 }
1956
1957 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001958 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001959 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001960 return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
Elliott Hughes814e4032011-08-23 12:07:56 -07001961 }
1962
Ian Rogersbc939662013-08-15 10:26:54 -07001963 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1964 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001965 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001966 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001967 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001968 if (start < 0 || length < 0 || start + length > s->GetLength()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001969 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001970 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001971 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001972 const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
1973 memcpy(buf, chars + start, length * sizeof(jchar));
1974 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001975 }
1976
Ian Rogersbc939662013-08-15 10:26:54 -07001977 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1978 char* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07001979 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001980 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001981 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001982 if (start < 0 || length < 0 || start + length > s->GetLength()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001983 ThrowSIOOBE(soa, start, length, s->GetLength());
Elliott Hughesb465ab02011-08-24 11:21:21 -07001984 } else {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001985 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
Elliott Hughesb465ab02011-08-24 11:21:21 -07001986 const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
1987 ConvertUtf16ToModifiedUtf8(buf, chars + start, length);
1988 }
Elliott Hughes814e4032011-08-23 12:07:56 -07001989 }
1990
Elliott Hughes75770752011-08-24 17:52:38 -07001991 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07001992 CHECK_NON_NULL_ARGUMENT(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001993 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08001994 mirror::String* s = soa.Decode<mirror::String*>(java_string);
1995 mirror::CharArray* chars = s->GetCharArray();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001996 PinPrimitiveArray(soa, chars);
Fred Shih56890e22014-06-02 11:11:52 -07001997 gc::Heap* heap = Runtime::Current()->GetHeap();
1998 if (heap->IsMovableObject(chars)) {
1999 if (is_copy != nullptr) {
2000 *is_copy = JNI_TRUE;
2001 }
2002 int32_t char_count = s->GetLength();
2003 int32_t offset = s->GetOffset();
2004 jchar* bytes = new jchar[char_count];
2005 for (int32_t i = 0; i < char_count; i++) {
2006 bytes[i] = chars->Get(i + offset);
2007 }
2008 return bytes;
2009 } else {
2010 if (is_copy != nullptr) {
2011 *is_copy = JNI_FALSE;
2012 }
2013 return static_cast<jchar*>(chars->GetData() + s->GetOffset());
Elliott Hughes75770752011-08-24 17:52:38 -07002014 }
Elliott Hughes814e4032011-08-23 12:07:56 -07002015 }
2016
Mathieu Chartier590fee92013-09-13 13:46:47 -07002017 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002018 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002019 ScopedObjectAccess soa(env);
Fred Shih56890e22014-06-02 11:11:52 -07002020 mirror::String* s = soa.Decode<mirror::String*>(java_string);
2021 mirror::CharArray* s_chars = s->GetCharArray();
2022 if (chars != (s_chars->GetData() + s->GetOffset())) {
2023 delete[] chars;
2024 }
2025 UnpinPrimitiveArray(soa, s->GetCharArray());
Elliott Hughescdf53122011-08-19 15:46:09 -07002026 }
2027
Elliott Hughes75770752011-08-24 17:52:38 -07002028 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Fred Shih56890e22014-06-02 11:11:52 -07002029 CHECK_NON_NULL_ARGUMENT(java_string);
2030 ScopedObjectAccess soa(env);
2031 mirror::String* s = soa.Decode<mirror::String*>(java_string);
2032 mirror::CharArray* chars = s->GetCharArray();
2033 int32_t offset = s->GetOffset();
2034 PinPrimitiveArray(soa, chars);
2035 gc::Heap* heap = Runtime::Current()->GetHeap();
2036 if (heap->IsMovableObject(chars)) {
2037 StackHandleScope<1> hs(soa.Self());
2038 HandleWrapper<mirror::CharArray> h(hs.NewHandleWrapper(&chars));
2039 heap->IncrementDisableMovingGC(soa.Self());
2040 }
2041 if (is_copy != nullptr) {
2042 *is_copy = JNI_FALSE;
2043 }
2044 return static_cast<jchar*>(chars->GetData() + offset);
Elliott Hughescdf53122011-08-19 15:46:09 -07002045 }
2046
Elliott Hughes75770752011-08-24 17:52:38 -07002047 static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) {
Fred Shih56890e22014-06-02 11:11:52 -07002048 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
2049 ScopedObjectAccess soa(env);
2050 UnpinPrimitiveArray(soa, soa.Decode<mirror::String*>(java_string)->GetCharArray());
2051 gc::Heap* heap = Runtime::Current()->GetHeap();
2052 mirror::String* s = soa.Decode<mirror::String*>(java_string);
2053 mirror::CharArray* s_chars = s->GetCharArray();
2054 if (heap->IsMovableObject(s_chars)) {
2055 heap->DecrementDisableMovingGC(soa.Self());
2056 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002057 }
2058
Elliott Hughes75770752011-08-24 17:52:38 -07002059 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002060 if (java_string == nullptr) {
2061 return nullptr;
Elliott Hughes75770752011-08-24 17:52:38 -07002062 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002063 if (is_copy != nullptr) {
Elliott Hughes75770752011-08-24 17:52:38 -07002064 *is_copy = JNI_TRUE;
2065 }
Ian Rogersef28b142012-11-30 14:22:18 -08002066 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002067 mirror::String* s = soa.Decode<mirror::String*>(java_string);
Elliott Hughes75770752011-08-24 17:52:38 -07002068 size_t byte_count = s->GetUtfLength();
2069 char* bytes = new char[byte_count + 1];
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002070 CHECK(bytes != nullptr); // bionic aborts anyway.
Elliott Hughes75770752011-08-24 17:52:38 -07002071 const uint16_t* chars = s->GetCharArray()->GetData() + s->GetOffset();
2072 ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength());
2073 bytes[byte_count] = '\0';
2074 return bytes;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002075 }
2076
Elliott Hughes75770752011-08-24 17:52:38 -07002077 static void ReleaseStringUTFChars(JNIEnv* env, jstring, const char* chars) {
Elliott Hughes75770752011-08-24 17:52:38 -07002078 delete[] chars;
Elliott Hughesb465ab02011-08-24 11:21:21 -07002079 }
2080
Elliott Hughesbd935992011-08-22 11:59:34 -07002081 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002082 CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002083 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002084 mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
Brian Carlstromea46f952013-07-30 01:26:50 -07002085 if (UNLIKELY(!obj->IsArrayInstance())) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002086 JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
2087 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002088 mirror::Array* array = obj->AsArray();
Elliott Hughesbd935992011-08-22 11:59:34 -07002089 return array->GetLength();
Elliott Hughescdf53122011-08-19 15:46:09 -07002090 }
2091
Elliott Hughes814e4032011-08-23 12:07:56 -07002092 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07002093 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002094 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002095 mirror::ObjectArray<mirror::Object>* array =
2096 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002097 return soa.AddLocalReference<jobject>(array->Get(index));
Elliott Hughescdf53122011-08-19 15:46:09 -07002098 }
2099
Ian Rogersbc939662013-08-15 10:26:54 -07002100 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
2101 jobject java_value) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002102 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002103 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002104 mirror::ObjectArray<mirror::Object>* array =
2105 soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
2106 mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002107 array->Set<false>(index, value);
Elliott Hughescdf53122011-08-19 15:46:09 -07002108 }
2109
2110 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002111 return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002112 }
2113
2114 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002115 return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002116 }
2117
2118 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002119 return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002120 }
2121
2122 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002123 return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002124 }
2125
2126 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002127 return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002128 }
2129
2130 static jintArray NewIntArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002131 return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002132 }
2133
2134 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002135 return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002136 }
2137
Ian Rogers1d99e452014-01-02 17:36:41 -08002138 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
2139 jobject initial_element) {
2140 if (UNLIKELY(length < 0)) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002141 JniAbortF("NewObjectArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002142 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002143 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002144 CHECK_NON_NULL_ARGUMENT(element_jclass);
Elliott Hughescdf53122011-08-19 15:46:09 -07002145
2146 // Compute the array class corresponding to the given element class.
Brian Carlstromea46f952013-07-30 01:26:50 -07002147 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002148 mirror::Class* array_class;
Ian Rogers1d99e452014-01-02 17:36:41 -08002149 {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002150 mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
Ian Rogers1d99e452014-01-02 17:36:41 -08002151 if (UNLIKELY(element_class->IsPrimitive())) {
2152 JniAbortF("NewObjectArray", "not an object type: %s",
2153 PrettyDescriptor(element_class).c_str());
2154 return nullptr;
2155 }
Ian Rogers1d99e452014-01-02 17:36:41 -08002156 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartierb74cd292014-05-29 14:31:33 -07002157 array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
Ian Rogers1d99e452014-01-02 17:36:41 -08002158 if (UNLIKELY(array_class == nullptr)) {
2159 return nullptr;
2160 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002161 }
2162
Elliott Hughes75770752011-08-24 17:52:38 -07002163 // Allocate and initialize if necessary.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002164 mirror::ObjectArray<mirror::Object>* result =
2165 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002166 if (result != nullptr && initial_element != nullptr) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002167 mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
Ian Rogers1d99e452014-01-02 17:36:41 -08002168 if (initial_object != nullptr) {
2169 mirror::Class* element_class = result->GetClass()->GetComponentType();
2170 if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
2171 JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with element "
2172 "type of '%s'", PrettyDescriptor(initial_object->GetClass()).c_str(),
2173 PrettyDescriptor(element_class).c_str());
2174
2175 } else {
2176 for (jsize i = 0; i < length; ++i) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002177 result->SetWithoutChecks<false>(i, initial_object);
Ian Rogers1d99e452014-01-02 17:36:41 -08002178 }
2179 }
Elliott Hughes75770752011-08-24 17:52:38 -07002180 }
2181 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002182 return soa.AddLocalReference<jobjectArray>(result);
Elliott Hughescdf53122011-08-19 15:46:09 -07002183 }
2184
2185 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002186 return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
Elliott Hughescdf53122011-08-19 15:46:09 -07002187 }
2188
Ian Rogersa15e67d2012-02-28 13:51:55 -08002189 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
Mathieu Chartier3b60fea2014-04-24 17:17:21 -07002190 CHECK_NON_NULL_ARGUMENT(java_array);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002191 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002192 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07002193 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
2194 JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
2195 PrettyDescriptor(array->GetClass()).c_str());
2196 return nullptr;
2197 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002198 gc::Heap* heap = Runtime::Current()->GetHeap();
2199 if (heap->IsMovableObject(array)) {
Mathieu Chartier1d27b342014-01-28 12:51:09 -08002200 heap->IncrementDisableMovingGC(soa.Self());
Mathieu Chartier590fee92013-09-13 13:46:47 -07002201 // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002202 array = soa.Decode<mirror::Array*>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002203 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002204 PinPrimitiveArray(soa, array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002205 if (is_copy != nullptr) {
Ian Rogersa15e67d2012-02-28 13:51:55 -08002206 *is_copy = JNI_FALSE;
2207 }
Ian Rogersef7d42f2014-01-06 12:55:46 -08002208 return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002209 }
2210
Ian Rogers2d10b202014-05-12 19:15:18 -07002211 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
2212 jint mode) {
2213 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2214 ScopedObjectAccess soa(env);
2215 mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
2216 if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
2217 JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
2218 PrettyDescriptor(array->GetClass()).c_str());
2219 return;
2220 }
2221 const size_t component_size = array->GetClass()->GetComponentSize();
2222 ReleasePrimitiveArray(soa, array, component_size, elements, mode);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002223 }
2224
Elliott Hughes75770752011-08-24 17:52:38 -07002225 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002226 return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002227 }
2228
Elliott Hughes75770752011-08-24 17:52:38 -07002229 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002230 return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002231 }
2232
Elliott Hughes75770752011-08-24 17:52:38 -07002233 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002234 return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002235 }
2236
Elliott Hughes75770752011-08-24 17:52:38 -07002237 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002238 return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002239 }
2240
Elliott Hughes75770752011-08-24 17:52:38 -07002241 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002242 return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002243 }
2244
Elliott Hughes75770752011-08-24 17:52:38 -07002245 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002246 return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002247 }
2248
Elliott Hughes75770752011-08-24 17:52:38 -07002249 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002250 return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002251 }
2252
Elliott Hughes75770752011-08-24 17:52:38 -07002253 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002254 return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
Elliott Hughescdf53122011-08-19 15:46:09 -07002255 }
2256
Mathieu Chartier590fee92013-09-13 13:46:47 -07002257 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2258 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002259 ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
2260 mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002261 }
2262
Mathieu Chartier590fee92013-09-13 13:46:47 -07002263 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002264 ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002265 }
2266
Mathieu Chartier590fee92013-09-13 13:46:47 -07002267 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002268 ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002269 }
2270
Mathieu Chartier590fee92013-09-13 13:46:47 -07002271 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2272 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002273 ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002274 }
2275
Mathieu Chartier590fee92013-09-13 13:46:47 -07002276 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2277 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002278 ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002279 }
2280
Mathieu Chartier590fee92013-09-13 13:46:47 -07002281 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002282 ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002283 }
2284
Mathieu Chartier590fee92013-09-13 13:46:47 -07002285 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002286 ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002287 }
2288
Mathieu Chartier590fee92013-09-13 13:46:47 -07002289 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2290 jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002291 ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
Elliott Hughescdf53122011-08-19 15:46:09 -07002292 }
2293
Ian Rogersbc939662013-08-15 10:26:54 -07002294 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2295 jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002296 GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002297 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002298 }
2299
Ian Rogersbc939662013-08-15 10:26:54 -07002300 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2301 jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002302 GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002303 }
2304
Ian Rogersbc939662013-08-15 10:26:54 -07002305 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2306 jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002307 GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002308 }
2309
Ian Rogersbc939662013-08-15 10:26:54 -07002310 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2311 jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002312 GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002313 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002314 }
2315
Ian Rogersbc939662013-08-15 10:26:54 -07002316 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2317 jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002318 GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002319 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002320 }
2321
Ian Rogersbc939662013-08-15 10:26:54 -07002322 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2323 jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002324 GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002325 }
2326
Ian Rogersbc939662013-08-15 10:26:54 -07002327 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2328 jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002329 GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002330 }
2331
Ian Rogersbc939662013-08-15 10:26:54 -07002332 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2333 jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002334 GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002335 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002336 }
2337
Ian Rogersbc939662013-08-15 10:26:54 -07002338 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2339 const jboolean* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002340 SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002341 length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002342 }
2343
Ian Rogersbc939662013-08-15 10:26:54 -07002344 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2345 const jbyte* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002346 SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002347 }
2348
Ian Rogersbc939662013-08-15 10:26:54 -07002349 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2350 const jchar* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002351 SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002352 }
2353
Ian Rogersbc939662013-08-15 10:26:54 -07002354 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2355 const jdouble* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002356 SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002357 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002358 }
2359
Ian Rogersbc939662013-08-15 10:26:54 -07002360 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2361 const jfloat* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002362 SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08002363 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002364 }
2365
Ian Rogersbc939662013-08-15 10:26:54 -07002366 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2367 const jint* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002368 SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002369 }
2370
Ian Rogersbc939662013-08-15 10:26:54 -07002371 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2372 const jlong* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002373 SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002374 }
2375
Ian Rogersbc939662013-08-15 10:26:54 -07002376 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2377 const jshort* buf) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002378 SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002379 buf);
Elliott Hughescdf53122011-08-19 15:46:09 -07002380 }
2381
Ian Rogersbc939662013-08-15 10:26:54 -07002382 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2383 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002384 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2385 }
2386
Ian Rogersbc939662013-08-15 10:26:54 -07002387 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2388 jint method_count, bool return_errors) {
2389 if (UNLIKELY(method_count < 0)) {
Elliott Hughesaa836f72013-08-20 16:57:23 -07002390 JniAbortF("RegisterNatives", "negative method count: %d", method_count);
Ian Rogersbc939662013-08-15 10:26:54 -07002391 return JNI_ERR; // Not reached.
2392 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002393 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002394 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002395 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Ian Rogersbc939662013-08-15 10:26:54 -07002396 if (UNLIKELY(method_count == 0)) {
2397 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2398 << PrettyDescriptor(c);
2399 return JNI_OK;
2400 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002401 CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
Ian Rogersbc939662013-08-15 10:26:54 -07002402 for (jint i = 0; i < method_count; ++i) {
Elliott Hughescdf53122011-08-19 15:46:09 -07002403 const char* name = methods[i].name;
2404 const char* sig = methods[i].signature;
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002405 const void* fnPtr = methods[i].fnPtr;
2406 if (UNLIKELY(name == nullptr)) {
2407 ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2408 return JNI_ERR;
2409 } else if (UNLIKELY(sig == nullptr)) {
2410 ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2411 return JNI_ERR;
2412 } else if (UNLIKELY(fnPtr == nullptr)) {
2413 ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2414 return JNI_ERR;
2415 }
Ian Rogers1eb512d2013-10-18 15:42:20 -07002416 bool is_fast = false;
Elliott Hughescdf53122011-08-19 15:46:09 -07002417 if (*sig == '!') {
Ian Rogers1eb512d2013-10-18 15:42:20 -07002418 is_fast = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07002419 ++sig;
2420 }
2421
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002422 mirror::ArtMethod* m = c->FindDirectMethod(name, sig);
2423 if (m == nullptr) {
Elliott Hughes5174fe62011-08-23 15:12:35 -07002424 m = c->FindVirtualMethod(name, sig);
Elliott Hughescdf53122011-08-19 15:46:09 -07002425 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002426 if (m == nullptr) {
Ian Rogers0177e532014-02-11 16:30:46 -08002427 c->DumpClass(LOG(ERROR), mirror::Class::kDumpClassFullDetail);
Elliott Hughesc8fece32013-01-02 11:27:23 -08002428 LOG(return_errors ? ERROR : FATAL) << "Failed to register native method "
Ian Rogers0177e532014-02-11 16:30:46 -08002429 << PrettyDescriptor(c) << "." << name << sig << " in "
2430 << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002431 ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
Elliott Hughescdf53122011-08-19 15:46:09 -07002432 return JNI_ERR;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002433 } else if (!m->IsNative()) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08002434 LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
Ian Rogersbc939662013-08-15 10:26:54 -07002435 << PrettyDescriptor(c) << "." << name << sig
2436 << " as native";
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002437 ThrowNoSuchMethodError(soa, c, name, sig, "native");
Elliott Hughescdf53122011-08-19 15:46:09 -07002438 return JNI_ERR;
2439 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002440
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002441 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002442
Sebastien Hertzfa65e842014-07-03 09:39:53 +02002443 m->RegisterNative(soa.Self(), fnPtr, is_fast);
Elliott Hughescdf53122011-08-19 15:46:09 -07002444 }
2445 return JNI_OK;
2446 }
2447
Elliott Hughes5174fe62011-08-23 15:12:35 -07002448 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002449 CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002450 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002451 mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002452
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08002453 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
Elliott Hughes5174fe62011-08-23 15:12:35 -07002454
Ian Rogers2d10b202014-05-12 19:15:18 -07002455 size_t unregistered_count = 0;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002456 for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002457 mirror::ArtMethod* m = c->GetDirectMethod(i);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002458 if (m->IsNative()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002459 m->UnregisterNative(soa.Self());
Ian Rogers2d10b202014-05-12 19:15:18 -07002460 unregistered_count++;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002461 }
2462 }
2463 for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002464 mirror::ArtMethod* m = c->GetVirtualMethod(i);
Elliott Hughes5174fe62011-08-23 15:12:35 -07002465 if (m->IsNative()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002466 m->UnregisterNative(soa.Self());
Ian Rogers2d10b202014-05-12 19:15:18 -07002467 unregistered_count++;
Elliott Hughes5174fe62011-08-23 15:12:35 -07002468 }
2469 }
2470
Ian Rogers2d10b202014-05-12 19:15:18 -07002471 if (unregistered_count == 0) {
2472 LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2473 << PrettyDescriptor(c) << "' that contains no native methods";
2474 }
Elliott Hughes5174fe62011-08-23 15:12:35 -07002475 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002476 }
2477
Ian Rogers719d1a32014-03-06 12:13:39 -08002478 static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002479 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002480 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002481 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2482 o = o->MonitorEnter(soa.Self());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002483 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002484 return JNI_ERR;
2485 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002486 soa.Env()->monitors.Add(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002487 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002488 }
2489
Ian Rogers719d1a32014-03-06 12:13:39 -08002490 static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers2d10b202014-05-12 19:15:18 -07002491 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002492 ScopedObjectAccess soa(env);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002493 mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002494 o->MonitorExit(soa.Self());
2495 if (soa.Self()->IsExceptionPending()) {
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002496 return JNI_ERR;
2497 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002498 soa.Env()->monitors.Remove(o);
Elliott Hughesab7b9dc2012-03-27 13:16:29 -07002499 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07002500 }
2501
2502 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002503 CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
Elliott Hughescdf53122011-08-19 15:46:09 -07002504 Runtime* runtime = Runtime::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002505 if (runtime != nullptr) {
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002506 *vm = runtime->GetJavaVM();
Elliott Hughescdf53122011-08-19 15:46:09 -07002507 } else {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002508 *vm = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07002509 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002510 return (*vm != nullptr) ? JNI_OK : JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07002511 }
2512
Elliott Hughescdf53122011-08-19 15:46:09 -07002513 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002514 if (capacity < 0) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002515 JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64, capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002516 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002517 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002518 if (address == nullptr && capacity != 0) {
2519 JniAbortF("NewDirectByteBuffer", "non-zero capacity for nullptr pointer: %" PRId64, capacity);
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002520 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002521 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002522
Brian Carlstrom85a93362014-06-25 09:30:52 -07002523 // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
Brian Carlstrom45d26c82014-06-24 23:36:28 -07002524 if (capacity > INT_MAX) {
2525 JniAbortF("NewDirectByteBuffer", "buffer capacity greater than maximum jint: %" PRId64, capacity);
2526 return nullptr;
2527 }
Elliott Hughesb5681212013-03-29 17:29:22 -07002528 jlong address_arg = reinterpret_cast<jlong>(address);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002529 jint capacity_arg = static_cast<jint>(capacity);
2530
Elliott Hughesaecb5f32013-03-28 08:27:38 -07002531 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2532 WellKnownClasses::java_nio_DirectByteBuffer_init,
Elliott Hugheseac76672012-05-24 21:56:51 -07002533 address_arg, capacity_arg);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002534 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
Elliott Hughescdf53122011-08-19 15:46:09 -07002535 }
2536
Elliott Hughesb465ab02011-08-24 11:21:21 -07002537 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002538 return reinterpret_cast<void*>(env->GetLongField(
2539 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
Elliott Hughescdf53122011-08-19 15:46:09 -07002540 }
2541
Elliott Hughesb465ab02011-08-24 11:21:21 -07002542 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002543 return static_cast<jlong>(env->GetIntField(
2544 java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
Elliott Hughescdf53122011-08-19 15:46:09 -07002545 }
2546
Elliott Hughesb465ab02011-08-24 11:21:21 -07002547 static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002548 CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNIInvalidRefType);
Elliott Hughesb465ab02011-08-24 11:21:21 -07002549
2550 // Do we definitely know what kind of reference this is?
2551 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2552 IndirectRefKind kind = GetIndirectRefKind(ref);
2553 switch (kind) {
Mathieu Chartierc645f1d2014-03-06 18:11:53 -08002554 case kLocal: {
2555 ScopedObjectAccess soa(env);
Hiroshi Yamauchi196851b2014-05-29 12:16:04 -07002556 // The local refs don't need a read barrier.
2557 if (static_cast<JNIEnvExt*>(env)->locals.Get<kWithoutReadBarrier>(ref) !=
2558 kInvalidIndirectRefObject) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -07002559 return JNILocalRefType;
2560 }
2561 return JNIInvalidRefType;
Mathieu Chartierc645f1d2014-03-06 18:11:53 -08002562 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002563 case kGlobal:
2564 return JNIGlobalRefType;
2565 case kWeakGlobal:
2566 return JNIWeakGlobalRefType;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002567 case kHandleScopeOrInvalid:
Elliott Hughesb465ab02011-08-24 11:21:21 -07002568 // Is it in a stack IRT?
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07002569 if (static_cast<JNIEnvExt*>(env)->self->HandleScopeContains(java_object)) {
Elliott Hughesb465ab02011-08-24 11:21:21 -07002570 return JNILocalRefType;
2571 }
Elliott Hughesb465ab02011-08-24 11:21:21 -07002572 return JNIInvalidRefType;
2573 }
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08002574 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
2575 return JNIInvalidRefType;
Elliott Hughescdf53122011-08-19 15:46:09 -07002576 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002577
2578 private:
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07002579 static jint EnsureLocalCapacity(ScopedObjectAccess& soa, jint desired_capacity,
2580 const char* caller) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002581 // TODO: we should try to expand the table if necessary.
Elliott Hughesaa836f72013-08-20 16:57:23 -07002582 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002583 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2584 return JNI_ERR;
2585 }
2586 // TODO: this isn't quite right, since "capacity" includes holes.
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07002587 const size_t capacity = soa.Env()->locals.Capacity();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002588 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2589 if (!okay) {
2590 soa.Self()->ThrowOutOfMemoryError(caller);
2591 }
2592 return okay ? JNI_OK : JNI_ERR;
2593 }
2594
2595 template<typename JniT, typename ArtT>
Ian Rogers2d10b202014-05-12 19:15:18 -07002596 static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
Ian Rogers1d99e452014-01-02 17:36:41 -08002597 if (UNLIKELY(length < 0)) {
Elliott Hughes96a98872012-12-19 14:21:15 -08002598 JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
Ian Rogers1d99e452014-01-02 17:36:41 -08002599 return nullptr;
Elliott Hughes96a98872012-12-19 14:21:15 -08002600 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002601 ScopedObjectAccess soa(env);
Ian Rogers50b35e22012-10-04 10:09:15 -07002602 ArtT* result = ArtT::Alloc(soa.Self(), length);
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002603 return soa.AddLocalReference<JniT>(result);
2604 }
2605
Ian Rogers2d10b202014-05-12 19:15:18 -07002606 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2607 static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2608 const char* fn_name, const char* operation)
Ian Rogersb726dcb2012-09-05 08:57:23 -07002609 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002610 ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
Ian Rogers2d10b202014-05-12 19:15:18 -07002611 if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
2612 JniAbortF(fn_name, "attempt to %s %s primitive array elements with an object of type %s",
2613 operation, PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2614 PrettyDescriptor(array->GetClass()).c_str());
2615 return nullptr;
2616 }
2617 DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
2618 return array;
2619 }
2620
2621 template <typename ArrayT, typename ElementT, typename ArtArrayT>
2622 static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2623 CHECK_NON_NULL_ARGUMENT(java_array);
2624 ScopedObjectAccess soa(env);
2625 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2626 "GetArrayElements",
2627 "get");
2628 if (UNLIKELY(array == nullptr)) {
2629 return nullptr;
2630 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002631 PinPrimitiveArray(soa, array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002632 // Only make a copy if necessary.
2633 if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2634 if (is_copy != nullptr) {
2635 *is_copy = JNI_TRUE;
2636 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002637 const size_t component_size = sizeof(ElementT);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002638 size_t size = array->GetLength() * component_size;
2639 void* data = new uint64_t[RoundUp(size, 8) / 8];
2640 memcpy(data, array->GetData(), size);
Ian Rogers2d10b202014-05-12 19:15:18 -07002641 return reinterpret_cast<ElementT*>(data);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002642 } else {
2643 if (is_copy != nullptr) {
2644 *is_copy = JNI_FALSE;
2645 }
Ian Rogers2d10b202014-05-12 19:15:18 -07002646 return reinterpret_cast<ElementT*>(array->GetData());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002647 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002648 }
2649
Ian Rogers2d10b202014-05-12 19:15:18 -07002650 template <typename ArrayT, typename ElementT, typename ArtArrayT>
Mathieu Chartier590fee92013-09-13 13:46:47 -07002651 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
Ian Rogers2d10b202014-05-12 19:15:18 -07002652 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002653 ScopedObjectAccess soa(env);
Ian Rogers2d10b202014-05-12 19:15:18 -07002654 ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2655 "ReleaseArrayElements",
2656 "release");
2657 if (array == nullptr) {
2658 return;
2659 }
2660 ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2661 }
2662
2663 static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2664 size_t component_size, void* elements, jint mode)
2665 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002666 void* array_data = array->GetRawData(component_size, 0);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002667 gc::Heap* heap = Runtime::Current()->GetHeap();
Ian Rogers2d10b202014-05-12 19:15:18 -07002668 bool is_copy = array_data != elements;
Mathieu Chartier590fee92013-09-13 13:46:47 -07002669 size_t bytes = array->GetLength() * component_size;
Ian Rogers2d10b202014-05-12 19:15:18 -07002670 VLOG(heap) << "Release primitive array " << soa.Env() << " array_data " << array_data
2671 << " elements " << elements;
Mathieu Chartierd68ac702014-02-11 14:50:51 -08002672 if (is_copy) {
2673 // Sanity check: If elements is not the same as the java array's data, it better not be a
2674 // heap address. TODO: This might be slow to check, may be worth keeping track of which
2675 // copies we make?
2676 if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
2677 JniAbortF("ReleaseArrayElements", "invalid element pointer %p, array elements are %p",
2678 reinterpret_cast<void*>(elements), array_data);
2679 return;
2680 }
2681 }
Mathieu Chartier590fee92013-09-13 13:46:47 -07002682 // Don't need to copy if we had a direct pointer.
2683 if (mode != JNI_ABORT && is_copy) {
2684 memcpy(array_data, elements, bytes);
2685 }
2686 if (mode != JNI_COMMIT) {
2687 if (is_copy) {
2688 delete[] reinterpret_cast<uint64_t*>(elements);
Mathieu Chartier3e8b2e12014-01-19 17:17:26 -08002689 } else if (heap->IsMovableObject(array)) {
Mathieu Chartier1d27b342014-01-28 12:51:09 -08002690 // Non copy to a movable object must means that we had disabled the moving GC.
2691 heap->DecrementDisableMovingGC(soa.Self());
Mathieu Chartier590fee92013-09-13 13:46:47 -07002692 }
Mathieu Chartier3e8b2e12014-01-19 17:17:26 -08002693 UnpinPrimitiveArray(soa, array);
Mathieu Chartier590fee92013-09-13 13:46:47 -07002694 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002695 }
2696
Ian Rogers2d10b202014-05-12 19:15:18 -07002697 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2698 static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2699 jsize start, jsize length, ElementT* buf) {
2700 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2701 ScopedObjectAccess soa(env);
2702 ArtArrayT* array =
2703 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2704 "GetPrimitiveArrayRegion",
2705 "get region of");
2706 if (array != nullptr) {
2707 if (start < 0 || length < 0 || start + length > array->GetLength()) {
2708 ThrowAIOOBE(soa, array, start, length, "src");
2709 } else {
2710 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2711 ElementT* data = array->GetData();
2712 memcpy(buf, data + start, length * sizeof(ElementT));
2713 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002714 }
2715 }
2716
Ian Rogers2d10b202014-05-12 19:15:18 -07002717 template <typename JArrayT, typename ElementT, typename ArtArrayT>
2718 static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2719 jsize start, jsize length, const ElementT* buf) {
2720 CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2721 ScopedObjectAccess soa(env);
2722 ArtArrayT* array =
2723 DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2724 "SetPrimitiveArrayRegion",
2725 "set region of");
2726 if (array != nullptr) {
2727 if (start < 0 || length < 0 || start + length > array->GetLength()) {
2728 ThrowAIOOBE(soa, array, start, length, "dst");
2729 } else {
2730 CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2731 ElementT* data = array->GetData();
2732 memcpy(data + start, buf, length * sizeof(ElementT));
2733 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07002734 }
2735 }
Elliott Hughescdf53122011-08-19 15:46:09 -07002736};
Carl Shapiroea4dca82011-08-01 13:45:38 -07002737
Elliott Hughes88c5c352012-03-15 18:49:48 -07002738const JNINativeInterface gJniNativeInterface = {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08002739 nullptr, // reserved0.
2740 nullptr, // reserved1.
2741 nullptr, // reserved2.
2742 nullptr, // reserved3.
Elliott Hughescdf53122011-08-19 15:46:09 -07002743 JNI::GetVersion,
2744 JNI::DefineClass,
2745 JNI::FindClass,
2746 JNI::FromReflectedMethod,
2747 JNI::FromReflectedField,
2748 JNI::ToReflectedMethod,
2749 JNI::GetSuperclass,
2750 JNI::IsAssignableFrom,
2751 JNI::ToReflectedField,
2752 JNI::Throw,
2753 JNI::ThrowNew,
2754 JNI::ExceptionOccurred,
2755 JNI::ExceptionDescribe,
2756 JNI::ExceptionClear,
2757 JNI::FatalError,
2758 JNI::PushLocalFrame,
2759 JNI::PopLocalFrame,
2760 JNI::NewGlobalRef,
2761 JNI::DeleteGlobalRef,
2762 JNI::DeleteLocalRef,
2763 JNI::IsSameObject,
2764 JNI::NewLocalRef,
2765 JNI::EnsureLocalCapacity,
2766 JNI::AllocObject,
2767 JNI::NewObject,
2768 JNI::NewObjectV,
2769 JNI::NewObjectA,
2770 JNI::GetObjectClass,
2771 JNI::IsInstanceOf,
2772 JNI::GetMethodID,
2773 JNI::CallObjectMethod,
2774 JNI::CallObjectMethodV,
2775 JNI::CallObjectMethodA,
2776 JNI::CallBooleanMethod,
2777 JNI::CallBooleanMethodV,
2778 JNI::CallBooleanMethodA,
2779 JNI::CallByteMethod,
2780 JNI::CallByteMethodV,
2781 JNI::CallByteMethodA,
2782 JNI::CallCharMethod,
2783 JNI::CallCharMethodV,
2784 JNI::CallCharMethodA,
2785 JNI::CallShortMethod,
2786 JNI::CallShortMethodV,
2787 JNI::CallShortMethodA,
2788 JNI::CallIntMethod,
2789 JNI::CallIntMethodV,
2790 JNI::CallIntMethodA,
2791 JNI::CallLongMethod,
2792 JNI::CallLongMethodV,
2793 JNI::CallLongMethodA,
2794 JNI::CallFloatMethod,
2795 JNI::CallFloatMethodV,
2796 JNI::CallFloatMethodA,
2797 JNI::CallDoubleMethod,
2798 JNI::CallDoubleMethodV,
2799 JNI::CallDoubleMethodA,
2800 JNI::CallVoidMethod,
2801 JNI::CallVoidMethodV,
2802 JNI::CallVoidMethodA,
2803 JNI::CallNonvirtualObjectMethod,
2804 JNI::CallNonvirtualObjectMethodV,
2805 JNI::CallNonvirtualObjectMethodA,
2806 JNI::CallNonvirtualBooleanMethod,
2807 JNI::CallNonvirtualBooleanMethodV,
2808 JNI::CallNonvirtualBooleanMethodA,
2809 JNI::CallNonvirtualByteMethod,
2810 JNI::CallNonvirtualByteMethodV,
2811 JNI::CallNonvirtualByteMethodA,
2812 JNI::CallNonvirtualCharMethod,
2813 JNI::CallNonvirtualCharMethodV,
2814 JNI::CallNonvirtualCharMethodA,
2815 JNI::CallNonvirtualShortMethod,
2816 JNI::CallNonvirtualShortMethodV,
2817 JNI::CallNonvirtualShortMethodA,
2818 JNI::CallNonvirtualIntMethod,
2819 JNI::CallNonvirtualIntMethodV,
2820 JNI::CallNonvirtualIntMethodA,
2821 JNI::CallNonvirtualLongMethod,
2822 JNI::CallNonvirtualLongMethodV,
2823 JNI::CallNonvirtualLongMethodA,
2824 JNI::CallNonvirtualFloatMethod,
2825 JNI::CallNonvirtualFloatMethodV,
2826 JNI::CallNonvirtualFloatMethodA,
2827 JNI::CallNonvirtualDoubleMethod,
2828 JNI::CallNonvirtualDoubleMethodV,
2829 JNI::CallNonvirtualDoubleMethodA,
2830 JNI::CallNonvirtualVoidMethod,
2831 JNI::CallNonvirtualVoidMethodV,
2832 JNI::CallNonvirtualVoidMethodA,
2833 JNI::GetFieldID,
2834 JNI::GetObjectField,
2835 JNI::GetBooleanField,
2836 JNI::GetByteField,
2837 JNI::GetCharField,
2838 JNI::GetShortField,
2839 JNI::GetIntField,
2840 JNI::GetLongField,
2841 JNI::GetFloatField,
2842 JNI::GetDoubleField,
2843 JNI::SetObjectField,
2844 JNI::SetBooleanField,
2845 JNI::SetByteField,
2846 JNI::SetCharField,
2847 JNI::SetShortField,
2848 JNI::SetIntField,
2849 JNI::SetLongField,
2850 JNI::SetFloatField,
2851 JNI::SetDoubleField,
2852 JNI::GetStaticMethodID,
2853 JNI::CallStaticObjectMethod,
2854 JNI::CallStaticObjectMethodV,
2855 JNI::CallStaticObjectMethodA,
2856 JNI::CallStaticBooleanMethod,
2857 JNI::CallStaticBooleanMethodV,
2858 JNI::CallStaticBooleanMethodA,
2859 JNI::CallStaticByteMethod,
2860 JNI::CallStaticByteMethodV,
2861 JNI::CallStaticByteMethodA,
2862 JNI::CallStaticCharMethod,
2863 JNI::CallStaticCharMethodV,
2864 JNI::CallStaticCharMethodA,
2865 JNI::CallStaticShortMethod,
2866 JNI::CallStaticShortMethodV,
2867 JNI::CallStaticShortMethodA,
2868 JNI::CallStaticIntMethod,
2869 JNI::CallStaticIntMethodV,
2870 JNI::CallStaticIntMethodA,
2871 JNI::CallStaticLongMethod,
2872 JNI::CallStaticLongMethodV,
2873 JNI::CallStaticLongMethodA,
2874 JNI::CallStaticFloatMethod,
2875 JNI::CallStaticFloatMethodV,
2876 JNI::CallStaticFloatMethodA,
2877 JNI::CallStaticDoubleMethod,
2878 JNI::CallStaticDoubleMethodV,
2879 JNI::CallStaticDoubleMethodA,
2880 JNI::CallStaticVoidMethod,
2881 JNI::CallStaticVoidMethodV,
2882 JNI::CallStaticVoidMethodA,
2883 JNI::GetStaticFieldID,
2884 JNI::GetStaticObjectField,
2885 JNI::GetStaticBooleanField,
2886 JNI::GetStaticByteField,
2887 JNI::GetStaticCharField,
2888 JNI::GetStaticShortField,
2889 JNI::GetStaticIntField,
2890 JNI::GetStaticLongField,
2891 JNI::GetStaticFloatField,
2892 JNI::GetStaticDoubleField,
2893 JNI::SetStaticObjectField,
2894 JNI::SetStaticBooleanField,
2895 JNI::SetStaticByteField,
2896 JNI::SetStaticCharField,
2897 JNI::SetStaticShortField,
2898 JNI::SetStaticIntField,
2899 JNI::SetStaticLongField,
2900 JNI::SetStaticFloatField,
2901 JNI::SetStaticDoubleField,
2902 JNI::NewString,
2903 JNI::GetStringLength,
2904 JNI::GetStringChars,
2905 JNI::ReleaseStringChars,
2906 JNI::NewStringUTF,
2907 JNI::GetStringUTFLength,
2908 JNI::GetStringUTFChars,
2909 JNI::ReleaseStringUTFChars,
2910 JNI::GetArrayLength,
2911 JNI::NewObjectArray,
2912 JNI::GetObjectArrayElement,
2913 JNI::SetObjectArrayElement,
2914 JNI::NewBooleanArray,
2915 JNI::NewByteArray,
2916 JNI::NewCharArray,
2917 JNI::NewShortArray,
2918 JNI::NewIntArray,
2919 JNI::NewLongArray,
2920 JNI::NewFloatArray,
2921 JNI::NewDoubleArray,
2922 JNI::GetBooleanArrayElements,
2923 JNI::GetByteArrayElements,
2924 JNI::GetCharArrayElements,
2925 JNI::GetShortArrayElements,
2926 JNI::GetIntArrayElements,
2927 JNI::GetLongArrayElements,
2928 JNI::GetFloatArrayElements,
2929 JNI::GetDoubleArrayElements,
2930 JNI::ReleaseBooleanArrayElements,
2931 JNI::ReleaseByteArrayElements,
2932 JNI::ReleaseCharArrayElements,
2933 JNI::ReleaseShortArrayElements,
2934 JNI::ReleaseIntArrayElements,
2935 JNI::ReleaseLongArrayElements,
2936 JNI::ReleaseFloatArrayElements,
2937 JNI::ReleaseDoubleArrayElements,
2938 JNI::GetBooleanArrayRegion,
2939 JNI::GetByteArrayRegion,
2940 JNI::GetCharArrayRegion,
2941 JNI::GetShortArrayRegion,
2942 JNI::GetIntArrayRegion,
2943 JNI::GetLongArrayRegion,
2944 JNI::GetFloatArrayRegion,
2945 JNI::GetDoubleArrayRegion,
2946 JNI::SetBooleanArrayRegion,
2947 JNI::SetByteArrayRegion,
2948 JNI::SetCharArrayRegion,
2949 JNI::SetShortArrayRegion,
2950 JNI::SetIntArrayRegion,
2951 JNI::SetLongArrayRegion,
2952 JNI::SetFloatArrayRegion,
2953 JNI::SetDoubleArrayRegion,
2954 JNI::RegisterNatives,
2955 JNI::UnregisterNatives,
2956 JNI::MonitorEnter,
2957 JNI::MonitorExit,
2958 JNI::GetJavaVM,
2959 JNI::GetStringRegion,
2960 JNI::GetStringUTFRegion,
2961 JNI::GetPrimitiveArrayCritical,
2962 JNI::ReleasePrimitiveArrayCritical,
2963 JNI::GetStringCritical,
2964 JNI::ReleaseStringCritical,
2965 JNI::NewWeakGlobalRef,
2966 JNI::DeleteWeakGlobalRef,
2967 JNI::ExceptionCheck,
2968 JNI::NewDirectByteBuffer,
2969 JNI::GetDirectBufferAddress,
2970 JNI::GetDirectBufferCapacity,
2971 JNI::GetObjectRefType,
Carl Shapiroea4dca82011-08-01 13:45:38 -07002972};
2973
Elliott Hughes75770752011-08-24 17:52:38 -07002974JNIEnvExt::JNIEnvExt(Thread* self, JavaVMExt* vm)
Elliott Hughes69f5bc62011-08-24 09:26:14 -07002975 : self(self),
Elliott Hughes75770752011-08-24 17:52:38 -07002976 vm(vm),
Ian Rogers5a7a74a2011-09-26 16:32:29 -07002977 local_ref_cookie(IRT_FIRST_SEGMENT),
2978 locals(kLocalsInitial, kLocalsMax, kLocal),
Elliott Hughes4ffd3132011-10-24 12:06:42 -07002979 check_jni(false),
Ian Rogersdd7624d2014-03-14 17:43:00 -07002980 critical(0),
Ian Rogers5a7a74a2011-09-26 16:32:29 -07002981 monitors("monitors", kMonitorsInitial, kMonitorsMax) {
Elliott Hughes88c5c352012-03-15 18:49:48 -07002982 functions = unchecked_functions = &gJniNativeInterface;
Elliott Hughes4ffd3132011-10-24 12:06:42 -07002983 if (vm->check_jni) {
Elliott Hughes88c5c352012-03-15 18:49:48 -07002984 SetCheckJniEnabled(true);
Elliott Hughesa2501992011-08-26 19:39:54 -07002985 }
Elliott Hughes40ef99e2011-08-11 17:44:34 -07002986}
2987
Elliott Hughesc1674ed2011-08-25 18:09:09 -07002988JNIEnvExt::~JNIEnvExt() {
2989}
2990
Mathieu Chartier590fee92013-09-13 13:46:47 -07002991jobject JNIEnvExt::NewLocalRef(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2992 if (obj == nullptr) {
2993 return nullptr;
2994 }
2995 return reinterpret_cast<jobject>(locals.Add(local_ref_cookie, obj));
2996}
2997
2998void JNIEnvExt::DeleteLocalRef(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2999 if (obj != nullptr) {
3000 locals.Remove(local_ref_cookie, reinterpret_cast<IndirectRef>(obj));
3001 }
3002}
Elliott Hughes88c5c352012-03-15 18:49:48 -07003003void JNIEnvExt::SetCheckJniEnabled(bool enabled) {
3004 check_jni = enabled;
3005 functions = enabled ? GetCheckJniNativeInterface() : &gJniNativeInterface;
Elliott Hughes4ffd3132011-10-24 12:06:42 -07003006}
3007
Elliott Hughes73e66f72012-05-09 09:34:45 -07003008void JNIEnvExt::DumpReferenceTables(std::ostream& os) {
3009 locals.Dump(os);
3010 monitors.Dump(os);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07003011}
3012
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07003013void JNIEnvExt::PushFrame(int capacity) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
3014 UNUSED(capacity); // cpplint gets confused with (int) and thinks its a cast.
Elliott Hughes1bac54f2012-03-16 12:48:31 -07003015 // TODO: take 'capacity' into account.
Elliott Hughes2ced6a52011-10-16 18:44:48 -07003016 stacked_local_ref_cookies.push_back(local_ref_cookie);
3017 local_ref_cookie = locals.GetSegmentState();
3018}
3019
Yevgeny Rouban35aef2c2014-05-19 16:19:36 +07003020void JNIEnvExt::PopFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes2ced6a52011-10-16 18:44:48 -07003021 locals.SetSegmentState(local_ref_cookie);
3022 local_ref_cookie = stacked_local_ref_cookies.back();
3023 stacked_local_ref_cookies.pop_back();
3024}
3025
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08003026Offset JNIEnvExt::SegmentStateOffset() {
3027 return Offset(OFFSETOF_MEMBER(JNIEnvExt, locals) +
3028 IndirectReferenceTable::SegmentStateOffset().Int32Value());
3029}
3030
Carl Shapiroea4dca82011-08-01 13:45:38 -07003031// JNI Invocation interface.
3032
Brian Carlstrombddf9762013-05-14 11:35:37 -07003033extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003034 const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
Elliott Hughes83a25322013-03-14 11:18:53 -07003035 if (IsBadJniVersion(args->version)) {
3036 LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003037 return JNI_EVERSION;
3038 }
Ian Rogerse63db272014-07-15 15:36:11 -07003039 RuntimeOptions options;
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003040 for (int i = 0; i < args->nOptions; ++i) {
3041 JavaVMOption* option = &args->options[i];
Elliott Hughesf1a5adc2012-02-10 18:09:35 -08003042 options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003043 }
3044 bool ignore_unrecognized = args->ignoreUnrecognized;
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003045 if (!Runtime::Create(options, ignore_unrecognized)) {
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003046 return JNI_ERR;
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003047 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003048 Runtime* runtime = Runtime::Current();
Brian Carlstrombd86bcc2013-03-10 20:26:16 -07003049 bool started = runtime->Start();
3050 if (!started) {
3051 delete Thread::Current()->GetJniEnv();
3052 delete runtime->GetJavaVM();
3053 LOG(WARNING) << "CreateJavaVM failed";
3054 return JNI_ERR;
3055 }
Brian Carlstrom69b15fb2011-09-03 12:25:21 -07003056 *p_env = Thread::Current()->GetJniEnv();
3057 *p_vm = runtime->GetJavaVM();
3058 return JNI_OK;
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003059}
3060
Elliott Hughesf2682d52011-08-15 16:37:04 -07003061extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize, jsize* vm_count) {
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003062 Runtime* runtime = Runtime::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003063 if (runtime == nullptr) {
Elliott Hughesf2682d52011-08-15 16:37:04 -07003064 *vm_count = 0;
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003065 } else {
Elliott Hughesf2682d52011-08-15 16:37:04 -07003066 *vm_count = 1;
Elliott Hughes69f5bc62011-08-24 09:26:14 -07003067 vms[0] = runtime->GetJavaVM();
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003068 }
3069 return JNI_OK;
3070}
3071
3072// Historically unsupported.
Elliott Hughes1bac54f2012-03-16 12:48:31 -07003073extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) {
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003074 return JNI_ERR;
3075}
3076
Elliott Hughescdf53122011-08-19 15:46:09 -07003077class JII {
3078 public:
3079 static jint DestroyJavaVM(JavaVM* vm) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003080 if (vm == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -07003081 return JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07003082 }
Elliott Hughes6a144332012-04-03 13:07:11 -07003083 JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
3084 delete raw_vm->runtime;
3085 return JNI_OK;
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003086 }
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003087
Elliott Hughescdf53122011-08-19 15:46:09 -07003088 static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
Elliott Hughes75770752011-08-24 17:52:38 -07003089 return JII_AttachCurrentThread(vm, p_env, thr_args, false);
Elliott Hughescdf53122011-08-19 15:46:09 -07003090 }
3091
3092 static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
Elliott Hughes75770752011-08-24 17:52:38 -07003093 return JII_AttachCurrentThread(vm, p_env, thr_args, true);
Elliott Hughescdf53122011-08-19 15:46:09 -07003094 }
3095
3096 static jint DetachCurrentThread(JavaVM* vm) {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003097 if (vm == nullptr || Thread::Current() == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -07003098 return JNI_ERR;
Elliott Hughescdf53122011-08-19 15:46:09 -07003099 }
Elliott Hughes6a144332012-04-03 13:07:11 -07003100 JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
3101 Runtime* runtime = raw_vm->runtime;
3102 runtime->DetachCurrentThread();
3103 return JNI_OK;
Elliott Hughescdf53122011-08-19 15:46:09 -07003104 }
3105
3106 static jint GetEnv(JavaVM* vm, void** env, jint version) {
Elliott Hughes3b7ffa12013-09-06 15:57:08 -07003107 // GetEnv always returns a JNIEnv* for the most current supported JNI version,
3108 // and unlike other calls that take a JNI version doesn't care if you supply
3109 // JNI_VERSION_1_1, which we don't otherwise support.
3110 if (IsBadJniVersion(version) && version != JNI_VERSION_1_1) {
Elliott Hughes83a25322013-03-14 11:18:53 -07003111 LOG(ERROR) << "Bad JNI version passed to GetEnv: " << version;
Elliott Hughescdf53122011-08-19 15:46:09 -07003112 return JNI_EVERSION;
3113 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003114 if (vm == nullptr || env == nullptr) {
Elliott Hughescdf53122011-08-19 15:46:09 -07003115 return JNI_ERR;
3116 }
3117 Thread* thread = Thread::Current();
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003118 if (thread == nullptr) {
3119 *env = nullptr;
Elliott Hughescdf53122011-08-19 15:46:09 -07003120 return JNI_EDETACHED;
3121 }
3122 *env = thread->GetJniEnv();
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003123 return JNI_OK;
3124 }
Elliott Hughescdf53122011-08-19 15:46:09 -07003125};
Carl Shapiro2ed144c2011-07-26 16:52:08 -07003126
Elliott Hughes88c5c352012-03-15 18:49:48 -07003127const JNIInvokeInterface gJniInvokeInterface = {
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003128 nullptr, // reserved0
3129 nullptr, // reserved1
3130 nullptr, // reserved2
Elliott Hughescdf53122011-08-19 15:46:09 -07003131 JII::DestroyJavaVM,
3132 JII::AttachCurrentThread,
3133 JII::DetachCurrentThread,
3134 JII::GetEnv,
3135 JII::AttachCurrentThreadAsDaemon
Carl Shapiroea4dca82011-08-01 13:45:38 -07003136};
3137
Brian Carlstrom491ca9e2014-03-02 18:24:38 -08003138JavaVMExt::JavaVMExt(Runtime* runtime, ParsedOptions* options)
Elliott Hughes69f5bc62011-08-24 09:26:14 -07003139 : runtime(runtime),
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003140 check_jni_abort_hook(nullptr),
3141 check_jni_abort_hook_data(nullptr),
Elliott Hughes4ffd3132011-10-24 12:06:42 -07003142 check_jni(false),
Brian Carlstrom7934ac22013-07-26 10:54:15 -07003143 force_copy(false), // TODO: add a way to enable this
Elliott Hughesa0957642011-09-02 14:27:33 -07003144 trace(options->jni_trace_),
Ian Rogers62d6c772013-02-27 08:32:07 -08003145 pins_lock("JNI pin table lock", kPinTableLock),
Elliott Hughes2ced6a52011-10-16 18:44:48 -07003146 pin_table("pin table", kPinTableInitial, kPinTableMax),
Elliott Hughes8daa0922011-09-11 13:46:25 -07003147 globals_lock("JNI global reference table lock"),
Elliott Hughesbb1e8f02011-10-18 14:14:25 -07003148 globals(gGlobalsInitial, gGlobalsMax, kGlobal),
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003149 libraries_lock("JNI shared libraries map lock", kLoadLibraryLock),
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003150 libraries(new Libraries),
3151 weak_globals_lock_("JNI weak global reference table lock"),
3152 weak_globals_(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal),
3153 allow_new_weak_globals_(true),
3154 weak_globals_add_condition_("weak globals add condition", weak_globals_lock_) {
Elliott Hughes88c5c352012-03-15 18:49:48 -07003155 functions = unchecked_functions = &gJniInvokeInterface;
Elliott Hughes4ffd3132011-10-24 12:06:42 -07003156 if (options->check_jni_) {
Elliott Hughes88c5c352012-03-15 18:49:48 -07003157 SetCheckJniEnabled(true);
Elliott Hughesa2501992011-08-26 19:39:54 -07003158 }
Elliott Hughesf2682d52011-08-15 16:37:04 -07003159}
3160
Elliott Hughesde69d7f2011-08-18 16:49:37 -07003161JavaVMExt::~JavaVMExt() {
Elliott Hughes79082e32011-08-25 12:07:32 -07003162 delete libraries;
Elliott Hughesde69d7f2011-08-18 16:49:37 -07003163}
3164
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003165jweak JavaVMExt::AddWeakGlobalReference(Thread* self, mirror::Object* obj) {
3166 if (obj == nullptr) {
3167 return nullptr;
3168 }
3169 MutexLock mu(self, weak_globals_lock_);
3170 while (UNLIKELY(!allow_new_weak_globals_)) {
3171 weak_globals_add_condition_.WaitHoldingLocks(self);
3172 }
3173 IndirectRef ref = weak_globals_.Add(IRT_FIRST_SEGMENT, obj);
3174 return reinterpret_cast<jweak>(ref);
3175}
3176
3177void JavaVMExt::DeleteWeakGlobalRef(Thread* self, jweak obj) {
3178 MutexLock mu(self, weak_globals_lock_);
3179 if (!weak_globals_.Remove(IRT_FIRST_SEGMENT, obj)) {
3180 LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
3181 << "failed to find entry";
3182 }
3183}
3184
Elliott Hughes88c5c352012-03-15 18:49:48 -07003185void JavaVMExt::SetCheckJniEnabled(bool enabled) {
3186 check_jni = enabled;
3187 functions = enabled ? GetCheckJniInvokeInterface() : &gJniInvokeInterface;
Elliott Hughes4ffd3132011-10-24 12:06:42 -07003188}
3189
Elliott Hughesae80b492012-04-24 10:43:17 -07003190void JavaVMExt::DumpForSigQuit(std::ostream& os) {
3191 os << "JNI: CheckJNI is " << (check_jni ? "on" : "off");
3192 if (force_copy) {
3193 os << " (with forcecopy)";
3194 }
Ian Rogers50b35e22012-10-04 10:09:15 -07003195 Thread* self = Thread::Current();
Elliott Hughesae80b492012-04-24 10:43:17 -07003196 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003197 MutexLock mu(self, pins_lock);
Elliott Hughesae80b492012-04-24 10:43:17 -07003198 os << "; pins=" << pin_table.Size();
3199 }
3200 {
Ian Rogersb8a0b942013-08-20 18:09:52 -07003201 ReaderMutexLock mu(self, globals_lock);
Elliott Hughesae80b492012-04-24 10:43:17 -07003202 os << "; globals=" << globals.Capacity();
3203 }
3204 {
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003205 MutexLock mu(self, weak_globals_lock_);
3206 if (weak_globals_.Capacity() > 0) {
3207 os << " (plus " << weak_globals_.Capacity() << " weak)";
Elliott Hughesae80b492012-04-24 10:43:17 -07003208 }
3209 }
3210 os << '\n';
3211
3212 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003213 MutexLock mu(self, libraries_lock);
Elliott Hughesae80b492012-04-24 10:43:17 -07003214 os << "Libraries: " << Dumpable<Libraries>(*libraries) << " (" << libraries->size() << ")\n";
3215 }
3216}
3217
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003218void JavaVMExt::DisallowNewWeakGlobals() {
3219 MutexLock mu(Thread::Current(), weak_globals_lock_);
3220 allow_new_weak_globals_ = false;
3221}
3222
3223void JavaVMExt::AllowNewWeakGlobals() {
3224 Thread* self = Thread::Current();
3225 MutexLock mu(self, weak_globals_lock_);
3226 allow_new_weak_globals_ = true;
3227 weak_globals_add_condition_.Broadcast(self);
3228}
3229
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003230mirror::Object* JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) {
3231 MutexLock mu(self, weak_globals_lock_);
3232 while (UNLIKELY(!allow_new_weak_globals_)) {
3233 weak_globals_add_condition_.WaitHoldingLocks(self);
3234 }
Hiroshi Yamauchiea2e1bd2014-06-18 13:47:35 -07003235 return weak_globals_.Get(ref);
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003236}
3237
Elliott Hughes73e66f72012-05-09 09:34:45 -07003238void JavaVMExt::DumpReferenceTables(std::ostream& os) {
Ian Rogers50b35e22012-10-04 10:09:15 -07003239 Thread* self = Thread::Current();
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07003240 {
Ian Rogersb8a0b942013-08-20 18:09:52 -07003241 ReaderMutexLock mu(self, globals_lock);
Elliott Hughes73e66f72012-05-09 09:34:45 -07003242 globals.Dump(os);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07003243 }
3244 {
Mathieu Chartierc11d9b82013-09-19 10:01:59 -07003245 MutexLock mu(self, weak_globals_lock_);
3246 weak_globals_.Dump(os);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07003247 }
3248 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003249 MutexLock mu(self, pins_lock);
Elliott Hughes73e66f72012-05-09 09:34:45 -07003250 pin_table.Dump(os);
Elliott Hughes9d5ccec2011-09-19 13:19:50 -07003251 }
3252}
3253
Mathieu Chartier055d46c2014-02-06 11:22:17 -08003254bool JavaVMExt::LoadNativeLibrary(const std::string& path,
Mathieu Chartier0cd81352014-05-22 16:48:55 -07003255 Handle<mirror::ClassLoader> class_loader,
Ian Rogers1eb512d2013-10-18 15:42:20 -07003256 std::string* detail) {
3257 detail->clear();
Elliott Hughescdf53122011-08-19 15:46:09 -07003258
3259 // See if we've already loaded this library. If we have, and the class loader
3260 // matches, return successfully without doing anything.
Elliott Hughes75770752011-08-24 17:52:38 -07003261 // TODO: for better results we should canonicalize the pathname (or even compare
3262 // inodes). This implementation is fine if everybody is using System.loadLibrary.
Elliott Hughes79082e32011-08-25 12:07:32 -07003263 SharedLibrary* library;
Ian Rogers50b35e22012-10-04 10:09:15 -07003264 Thread* self = Thread::Current();
Elliott Hughes79082e32011-08-25 12:07:32 -07003265 {
3266 // TODO: move the locking (and more of this logic) into Libraries.
Ian Rogers50b35e22012-10-04 10:09:15 -07003267 MutexLock mu(self, libraries_lock);
Elliott Hughes79082e32011-08-25 12:07:32 -07003268 library = libraries->Get(path);
3269 }
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003270 if (library != nullptr) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07003271 if (library->GetClassLoader() != class_loader.Get()) {
Elliott Hughes75770752011-08-24 17:52:38 -07003272 // The library will be associated with class_loader. The JNI
3273 // spec says we can't load the same library into more than one
3274 // class loader.
Ian Rogers1eb512d2013-10-18 15:42:20 -07003275 StringAppendF(detail, "Shared library \"%s\" already opened by "
Elliott Hughes75770752011-08-24 17:52:38 -07003276 "ClassLoader %p; can't open in ClassLoader %p",
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07003277 path.c_str(), library->GetClassLoader(), class_loader.Get());
Elliott Hughes75770752011-08-24 17:52:38 -07003278 LOG(WARNING) << detail;
Elliott Hughescdf53122011-08-19 15:46:09 -07003279 return false;
3280 }
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08003281 VLOG(jni) << "[Shared library \"" << path << "\" already loaded in "
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07003282 << "ClassLoader " << class_loader.Get() << "]";
Elliott Hughes1bac54f2012-03-16 12:48:31 -07003283 if (!library->CheckOnLoadResult()) {
Ian Rogers1eb512d2013-10-18 15:42:20 -07003284 StringAppendF(detail, "JNI_OnLoad failed on a previous attempt "
Elliott Hughes75770752011-08-24 17:52:38 -07003285 "to load \"%s\"", path.c_str());
Elliott Hughescdf53122011-08-19 15:46:09 -07003286 return false;
3287 }
3288 return true;
3289 }
3290
3291 // Open the shared library. Because we're using a full path, the system
3292 // doesn't have to search through LD_LIBRARY_PATH. (It may do so to
3293 // resolve this library's dependencies though.)
3294
3295 // Failures here are expected when java.library.path has several entries
3296 // and we have to hunt for the lib.
3297
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003298 // Below we dlopen but there is no paired dlclose, this would be necessary if we supported
3299 // class unloading. Libraries will only be unloaded when the reference count (incremented by
3300 // dlopen) becomes zero from dlclose.
3301
Elliott Hughescdf53122011-08-19 15:46:09 -07003302 // This can execute slowly for a large library on a busy system, so we
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003303 // want to switch from kRunnable while it executes. This allows the GC to ignore us.
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003304 self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
Yong WU355383f2014-07-24 21:32:15 +08003305 const char* path_str = path.empty() ? nullptr : path.c_str();
3306 void* handle = dlopen(path_str, RTLD_LAZY);
3307 bool needs_native_bridge = false;
3308 if (handle == nullptr) {
3309 if (NativeBridge::IsSupported(path_str)) {
3310 handle = NativeBridge::LoadLibrary(path_str, RTLD_LAZY);
3311 needs_native_bridge = true;
3312 }
3313 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003314 self->TransitionFromSuspendedToRunnable();
Elliott Hughescdf53122011-08-19 15:46:09 -07003315
Elliott Hughes84b2f142012-09-27 09:16:28 -07003316 VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_LAZY) returned " << handle << "]";
Elliott Hughescdf53122011-08-19 15:46:09 -07003317
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003318 if (handle == nullptr) {
Ian Rogers1eb512d2013-10-18 15:42:20 -07003319 *detail = dlerror();
Colin Cross35d5c3b2014-04-23 14:56:31 -07003320 LOG(ERROR) << "dlopen(\"" << path << "\", RTLD_LAZY) failed: " << *detail;
Elliott Hughescdf53122011-08-19 15:46:09 -07003321 return false;
3322 }
3323
3324 // Create a new entry.
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003325 // TODO: move the locking (and more of this logic) into Libraries.
3326 bool created_library = false;
Elliott Hughescdf53122011-08-19 15:46:09 -07003327 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003328 MutexLock mu(self, libraries_lock);
Elliott Hughes79082e32011-08-25 12:07:32 -07003329 library = libraries->Get(path);
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003330 if (library == nullptr) { // We won race to get libraries_lock
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07003331 library = new SharedLibrary(path, handle, class_loader.Get());
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003332 libraries->Put(path, library);
3333 created_library = true;
Elliott Hughescdf53122011-08-19 15:46:09 -07003334 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003335 }
3336 if (!created_library) {
3337 LOG(INFO) << "WOW: we lost a race to add shared library: "
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07003338 << "\"" << path << "\" ClassLoader=" << class_loader.Get();
Ian Rogers00f7d0e2012-07-19 15:28:27 -07003339 return library->CheckOnLoadResult();
Elliott Hughescdf53122011-08-19 15:46:09 -07003340 }
Elliott Hughes79082e32011-08-25 12:07:32 -07003341
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07003342 VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader.Get()
Mathieu Chartier055d46c2014-02-06 11:22:17 -08003343 << "]";
Elliott Hughes79082e32011-08-25 12:07:32 -07003344
Elliott Hughes79353722013-08-02 16:52:18 -07003345 bool was_successful = false;
Yong WU355383f2014-07-24 21:32:15 +08003346 void* sym = nullptr;
3347 if (UNLIKELY(needs_native_bridge)) {
3348 library->SetNeedsNativeBridge();
3349 sym = library->FindSymbolWithNativeBridge("JNI_OnLoad", nullptr);
3350 } else {
3351 sym = dlsym(handle, "JNI_OnLoad");
3352 }
3353
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003354 if (sym == nullptr) {
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08003355 VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]";
Elliott Hughes85affca2013-08-02 17:48:52 -07003356 was_successful = true;
Elliott Hughes79082e32011-08-25 12:07:32 -07003357 } else {
3358 // Call JNI_OnLoad. We have to override the current class
3359 // loader, which will always be "null" since the stuff at the
3360 // top of the stack is around Runtime.loadLibrary(). (See
3361 // the comments in the JNI FindClass function.)
3362 typedef int (*JNI_OnLoadFn)(JavaVM*, void*);
3363 JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07003364 StackHandleScope<1> hs(self);
3365 Handle<mirror::ClassLoader> old_class_loader(hs.NewHandle(self->GetClassLoaderOverride()));
3366 self->SetClassLoaderOverride(class_loader.Get());
Elliott Hughes79082e32011-08-25 12:07:32 -07003367
Elliott Hughesad7c2a32011-08-31 11:58:10 -07003368 int version = 0;
3369 {
Elliott Hughes34e06962012-04-09 13:55:55 -07003370 ScopedThreadStateChange tsc(self, kNative);
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -08003371 VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]";
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003372 version = (*jni_on_load)(this, nullptr);
Elliott Hughes79082e32011-08-25 12:07:32 -07003373 }
Elliott Hughes79082e32011-08-25 12:07:32 -07003374
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07003375 self->SetClassLoaderOverride(old_class_loader.Get());
Elliott Hughes79082e32011-08-25 12:07:32 -07003376
Elliott Hughes79353722013-08-02 16:52:18 -07003377 if (version == JNI_ERR) {
Ian Rogers1eb512d2013-10-18 15:42:20 -07003378 StringAppendF(detail, "JNI_ERR returned from JNI_OnLoad in \"%s\"", path.c_str());
Elliott Hughes79353722013-08-02 16:52:18 -07003379 } else if (IsBadJniVersion(version)) {
Ian Rogers1eb512d2013-10-18 15:42:20 -07003380 StringAppendF(detail, "Bad JNI version returned from JNI_OnLoad in \"%s\": %d",
Brian Carlstrom75fe90c2013-06-26 22:26:16 -07003381 path.c_str(), version);
Elliott Hughes79082e32011-08-25 12:07:32 -07003382 // It's unwise to call dlclose() here, but we can mark it
3383 // as bad and ensure that future load attempts will fail.
3384 // We don't know how far JNI_OnLoad got, so there could
3385 // be some partially-initialized stuff accessible through
3386 // newly-registered native method calls. We could try to
3387 // unregister them, but that doesn't seem worthwhile.
Elliott Hughes79353722013-08-02 16:52:18 -07003388 } else {
3389 was_successful = true;
Elliott Hughes79082e32011-08-25 12:07:32 -07003390 }
Elliott Hughes79353722013-08-02 16:52:18 -07003391 VLOG(jni) << "[Returned " << (was_successful ? "successfully" : "failure")
Brian Carlstrom75fe90c2013-06-26 22:26:16 -07003392 << " from JNI_OnLoad in \"" << path << "\"]";
Elliott Hughes79082e32011-08-25 12:07:32 -07003393 }
3394
Elliott Hughes79353722013-08-02 16:52:18 -07003395 library->SetResult(was_successful);
3396 return was_successful;
Elliott Hughes79082e32011-08-25 12:07:32 -07003397}
3398
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003399void* JavaVMExt::FindCodeForNativeMethod(mirror::ArtMethod* m) {
Elliott Hughes79082e32011-08-25 12:07:32 -07003400 CHECK(m->IsNative());
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003401 mirror::Class* c = m->GetDeclaringClass();
Ian Rogers6c5cb212014-06-18 16:07:20 -07003402 // If this is a static method, it could be called before the class has been initialized.
Elliott Hughes79082e32011-08-25 12:07:32 -07003403 if (m->IsStatic()) {
Mathieu Chartierc528dba2013-11-26 12:00:11 -08003404 c = EnsureInitialized(Thread::Current(), c);
3405 if (c == nullptr) {
3406 return nullptr;
Elliott Hughes79082e32011-08-25 12:07:32 -07003407 }
3408 } else {
Ian Rogersb8a0b942013-08-20 18:09:52 -07003409 CHECK(c->IsInitializing()) << c->GetStatus() << " " << PrettyMethod(m);
Elliott Hughes79082e32011-08-25 12:07:32 -07003410 }
Brian Carlstrom16192862011-09-12 17:50:06 -07003411 std::string detail;
3412 void* native_method;
Ian Rogers50b35e22012-10-04 10:09:15 -07003413 Thread* self = Thread::Current();
Brian Carlstrom16192862011-09-12 17:50:06 -07003414 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003415 MutexLock mu(self, libraries_lock);
Brian Carlstrom16192862011-09-12 17:50:06 -07003416 native_method = libraries->FindNativeMethod(m, detail);
3417 }
Ian Rogers62d6c772013-02-27 08:32:07 -08003418 // Throwing can cause libraries_lock to be reacquired.
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003419 if (native_method == nullptr) {
Ian Rogers62d6c772013-02-27 08:32:07 -08003420 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
3421 self->ThrowNewException(throw_location, "Ljava/lang/UnsatisfiedLinkError;", detail.c_str());
Brian Carlstrom16192862011-09-12 17:50:06 -07003422 }
3423 return native_method;
Elliott Hughescdf53122011-08-19 15:46:09 -07003424}
3425
Mathieu Chartier83c8ee02014-01-28 14:50:23 -08003426void JavaVMExt::SweepJniWeakGlobals(IsMarkedCallback* callback, void* arg) {
Mathieu Chartier810b1d72013-09-20 14:02:02 -07003427 MutexLock mu(Thread::Current(), weak_globals_lock_);
3428 for (mirror::Object** entry : weak_globals_) {
Hiroshi Yamauchi196851b2014-05-29 12:16:04 -07003429 // Since this is called by the GC, we don't need a read barrier.
Mathieu Chartier6aa3df92013-09-17 15:17:28 -07003430 mirror::Object* obj = *entry;
Mathieu Chartier83c8ee02014-01-28 14:50:23 -08003431 mirror::Object* new_obj = callback(obj, arg);
Mathieu Chartier6aa3df92013-09-17 15:17:28 -07003432 if (new_obj == nullptr) {
3433 new_obj = kClearedJniWeakGlobal;
3434 }
3435 *entry = new_obj;
3436 }
3437}
3438
Mathieu Chartier83c8ee02014-01-28 14:50:23 -08003439void JavaVMExt::VisitRoots(RootCallback* callback, void* arg) {
Ian Rogers50b35e22012-10-04 10:09:15 -07003440 Thread* self = Thread::Current();
Elliott Hughes410c0c82011-09-01 17:58:25 -07003441 {
Ian Rogersb8a0b942013-08-20 18:09:52 -07003442 ReaderMutexLock mu(self, globals_lock);
Mathieu Chartier83c8ee02014-01-28 14:50:23 -08003443 globals.VisitRoots(callback, arg, 0, kRootJNIGlobal);
Elliott Hughes410c0c82011-09-01 17:58:25 -07003444 }
3445 {
Ian Rogers50b35e22012-10-04 10:09:15 -07003446 MutexLock mu(self, pins_lock);
Mathieu Chartier83c8ee02014-01-28 14:50:23 -08003447 pin_table.VisitRoots(callback, arg, 0, kRootVMInternal);
Elliott Hughes410c0c82011-09-01 17:58:25 -07003448 }
Mathieu Chartier8f4be932014-01-28 15:25:19 -08003449 {
3450 MutexLock mu(self, libraries_lock);
3451 // Libraries contains shared libraries which hold a pointer to a class loader.
Mathieu Chartier83c8ee02014-01-28 14:50:23 -08003452 libraries->VisitRoots(callback, arg);
Mathieu Chartier8f4be932014-01-28 15:25:19 -08003453 }
Elliott Hughes410c0c82011-09-01 17:58:25 -07003454 // The weak_globals table is visited by the GC itself (because it mutates the table).
3455}
3456
Elliott Hughesc8fece32013-01-02 11:27:23 -08003457void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
Ian Rogersbc939662013-08-15 10:26:54 -07003458 jint method_count) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003459 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
Mathieu Chartiere7e8a5f2014-02-14 16:59:41 -08003460 if (c.get() == nullptr) {
Elliott Hughesc8fece32013-01-02 11:27:23 -08003461 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
3462 }
3463 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
3464}
3465
Ian Rogersdf20fe02011-07-20 20:34:16 -07003466} // namespace art
Elliott Hughesb465ab02011-08-24 11:21:21 -07003467
3468std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3469 switch (rhs) {
3470 case JNIInvalidRefType:
3471 os << "JNIInvalidRefType";
3472 return os;
3473 case JNILocalRefType:
3474 os << "JNILocalRefType";
3475 return os;
3476 case JNIGlobalRefType:
3477 os << "JNIGlobalRefType";
3478 return os;
3479 case JNIWeakGlobalRefType:
3480 os << "JNIWeakGlobalRefType";
3481 return os;
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003482 default:
Shih-wei Liao24782c62012-01-08 12:46:11 -08003483 LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
Brian Carlstrom2e3d1b22012-01-09 18:01:56 -08003484 return os;
Elliott Hughesb465ab02011-08-24 11:21:21 -07003485 }
3486}