blob: fefb907422c4a51118f4ad1a56b80c51716b477e [file] [log] [blame]
Elliott Hughesa2501992011-08-26 19:39:54 -07001/*
2 * Copyright (C) 2008 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 */
16
17#include "jni_internal.h"
18
19#include <sys/mman.h>
20#include <zlib.h>
21
Elliott Hughes07ed66b2012-12-12 18:34:25 -080022#include "base/logging.h"
Elliott Hughesa2501992011-08-26 19:39:54 -070023#include "class_linker.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080024#include "class_linker-inl.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070025#include "dex_file-inl.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070026#include "gc/space/space.h"
Brian Carlstromea46f952013-07-30 01:26:50 -070027#include "mirror/art_field-inl.h"
28#include "mirror/art_method-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080029#include "mirror/class-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080030#include "mirror/object-inl.h"
31#include "mirror/object_array-inl.h"
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070032#include "mirror/string-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080033#include "mirror/throwable.h"
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080034#include "object_utils.h"
Jeff Hao58df3272013-04-22 15:28:53 -070035#include "runtime.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070036#include "scoped_thread_state_change.h"
Elliott Hughesa2501992011-08-26 19:39:54 -070037#include "thread.h"
38
39namespace art {
40
Elliott Hughes3f6635a2012-06-19 13:37:49 -070041static void JniAbort(const char* jni_function_name, const char* msg) {
Elliott Hughesa0957642011-09-02 14:27:33 -070042 Thread* self = Thread::Current();
Ian Rogers00f7d0e2012-07-19 15:28:27 -070043 ScopedObjectAccess soa(self);
Ian Rogersef7d42f2014-01-06 12:55:46 -080044 mirror::ArtMethod* current_method = self->GetCurrentMethod(nullptr);
Elliott Hughesa2501992011-08-26 19:39:54 -070045
Elliott Hughes3b6baaa2011-10-14 19:13:56 -070046 std::ostringstream os;
Elliott Hughes3f6635a2012-06-19 13:37:49 -070047 os << "JNI DETECTED ERROR IN APPLICATION: " << msg;
Elliott Hughesa2501992011-08-26 19:39:54 -070048
Ian Rogersef7d42f2014-01-06 12:55:46 -080049 if (jni_function_name != nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -070050 os << "\n in call to " << jni_function_name;
Elliott Hughesa2501992011-08-26 19:39:54 -070051 }
Elliott Hughesa0957642011-09-02 14:27:33 -070052 // TODO: is this useful given that we're about to dump the calling thread's stack?
Ian Rogersef7d42f2014-01-06 12:55:46 -080053 if (current_method != nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -070054 os << "\n from " << PrettyMethod(current_method);
Elliott Hughesa0957642011-09-02 14:27:33 -070055 }
56 os << "\n";
57 self->Dump(os);
Elliott Hughesa2501992011-08-26 19:39:54 -070058
59 JavaVMExt* vm = Runtime::Current()->GetJavaVM();
Ian Rogersef7d42f2014-01-06 12:55:46 -080060 if (vm->check_jni_abort_hook != nullptr) {
Elliott Hughesb264f082012-04-06 17:10:10 -070061 vm->check_jni_abort_hook(vm->check_jni_abort_hook_data, os.str());
Elliott Hughesa2501992011-08-26 19:39:54 -070062 } else {
Ian Rogers9da7f592012-08-20 17:14:28 -070063 // Ensure that we get a native stack trace for this thread.
64 self->TransitionFromRunnableToSuspended(kNative);
Elliott Hughesa2501992011-08-26 19:39:54 -070065 LOG(FATAL) << os.str();
Ian Rogers9da7f592012-08-20 17:14:28 -070066 self->TransitionFromSuspendedToRunnable(); // Unreachable, keep annotalysis happy.
Elliott Hughesa2501992011-08-26 19:39:54 -070067 }
68}
69
Elliott Hughes3f6635a2012-06-19 13:37:49 -070070static void JniAbortV(const char* jni_function_name, const char* fmt, va_list ap) {
71 std::string msg;
72 StringAppendV(&msg, fmt, ap);
73 JniAbort(jni_function_name, msg.c_str());
74}
75
76void JniAbortF(const char* jni_function_name, const char* fmt, ...) {
77 va_list args;
78 va_start(args, fmt);
79 JniAbortV(jni_function_name, fmt, args);
80 va_end(args);
81}
82
Elliott Hughesa2501992011-08-26 19:39:54 -070083/*
84 * ===========================================================================
85 * JNI function helpers
86 * ===========================================================================
87 */
88
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070089static bool IsHandleScopeLocalRef(JNIEnv* env, jobject localRef) {
90 return GetIndirectRefKind(localRef) == kHandleScopeOrInvalid &&
91 reinterpret_cast<JNIEnvExt*>(env)->self->HandleScopeContains(localRef);
Ian Rogers959f8ed2012-02-07 16:33:37 -080092}
93
Elliott Hughes3f6635a2012-06-19 13:37:49 -070094// Flags passed into ScopedCheck.
Elliott Hughesa2501992011-08-26 19:39:54 -070095#define kFlag_Default 0x0000
96
Elliott Hughes3f6635a2012-06-19 13:37:49 -070097#define kFlag_CritBad 0x0000 // Calling while in critical is not allowed.
98#define kFlag_CritOkay 0x0001 // Calling while in critical is allowed.
99#define kFlag_CritGet 0x0002 // This is a critical "get".
100#define kFlag_CritRelease 0x0003 // This is a critical "release".
101#define kFlag_CritMask 0x0003 // Bit mask to get "crit" value.
Elliott Hughesa2501992011-08-26 19:39:54 -0700102
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700103#define kFlag_ExcepBad 0x0000 // Raised exceptions are not allowed.
104#define kFlag_ExcepOkay 0x0004 // Raised exceptions are allowed.
Elliott Hughesa2501992011-08-26 19:39:54 -0700105
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700106#define kFlag_Release 0x0010 // Are we in a non-critical release function?
107#define kFlag_NullableUtf 0x0020 // Are our UTF parameters nullable?
Elliott Hughesa2501992011-08-26 19:39:54 -0700108
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700109#define kFlag_Invocation 0x8000 // Part of the invocation interface (JavaVM*).
Elliott Hughesa2501992011-08-26 19:39:54 -0700110
Elliott Hughes485cac42011-12-09 17:49:35 -0800111#define kFlag_ForceTrace 0x80000000 // Add this to a JNI function's flags if you want to trace every call.
112
Elliott Hughesa0957642011-09-02 14:27:33 -0700113static const char* gBuiltInPrefixes[] = {
114 "Landroid/",
115 "Lcom/android/",
116 "Lcom/google/android/",
117 "Ldalvik/",
118 "Ljava/",
119 "Ljavax/",
120 "Llibcore/",
121 "Lorg/apache/harmony/",
Ian Rogersef7d42f2014-01-06 12:55:46 -0800122 nullptr
Elliott Hughesa0957642011-09-02 14:27:33 -0700123};
124
Ian Rogersef7d42f2014-01-06 12:55:46 -0800125static bool ShouldTrace(JavaVMExt* vm, mirror::ArtMethod* method)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700126 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa0957642011-09-02 14:27:33 -0700127 // If both "-Xcheck:jni" and "-Xjnitrace:" are enabled, we print trace messages
128 // when a native method that matches the -Xjnitrace argument calls a JNI function
129 // such as NewByteArray.
130 // If -verbose:third-party-jni is on, we want to log any JNI function calls
131 // made by a third-party native method.
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700132 std::string class_name(method->GetDeclaringClassDescriptor());
Elliott Hughes81ff3182012-03-23 20:35:56 -0700133 if (!vm->trace.empty() && class_name.find(vm->trace) != std::string::npos) {
Elliott Hughesa0957642011-09-02 14:27:33 -0700134 return true;
135 }
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800136 if (VLOG_IS_ON(third_party_jni)) {
Elliott Hughesa0957642011-09-02 14:27:33 -0700137 // Return true if we're trying to log all third-party JNI activity and 'method' doesn't look
138 // like part of Android.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800139 for (size_t i = 0; gBuiltInPrefixes[i] != nullptr; ++i) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700140 if (StartsWith(class_name, gBuiltInPrefixes[i])) {
Elliott Hughesa0957642011-09-02 14:27:33 -0700141 return false;
142 }
143 }
144 return true;
145 }
146 return false;
147}
148
Elliott Hughesa2501992011-08-26 19:39:54 -0700149class ScopedCheck {
Elliott Hughesba8eee12012-01-24 20:25:24 -0800150 public:
Elliott Hughesa2501992011-08-26 19:39:54 -0700151 // For JNIEnv* functions.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700152 explicit ScopedCheck(JNIEnv* env, int flags, const char* functionName)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700153 SHARED_LOCK_FUNCTION(Locks::mutator_lock_)
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700154 : soa_(env) {
Ian Rogers365c1022012-06-22 15:05:28 -0700155 Init(flags, functionName, true);
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700156 CheckThread(flags);
Elliott Hughesa2501992011-08-26 19:39:54 -0700157 }
158
159 // For JavaVM* functions.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700160 // TODO: it's not correct that this is a lock function, but making it so aids annotalysis.
161 explicit ScopedCheck(JavaVM* vm, bool has_method, const char* functionName)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700162 SHARED_LOCK_FUNCTION(Locks::mutator_lock_)
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700163 : soa_(vm) {
Ian Rogers365c1022012-06-22 15:05:28 -0700164 Init(kFlag_Invocation, functionName, has_method);
Elliott Hughesa2501992011-08-26 19:39:54 -0700165 }
166
Ian Rogersb726dcb2012-09-05 08:57:23 -0700167 ~ScopedCheck() UNLOCK_FUNCTION(Locks::mutator_lock_) {}
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700168
169 const ScopedObjectAccess& soa() {
170 return soa_;
171 }
172
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700173 bool ForceCopy() {
Elliott Hughesa2501992011-08-26 19:39:54 -0700174 return Runtime::Current()->GetJavaVM()->force_copy;
175 }
176
Elliott Hughes81ff3182012-03-23 20:35:56 -0700177 // Checks that 'class_name' is a valid "fully-qualified" JNI class name, like "java/lang/Thread"
178 // or "[Ljava/lang/Object;". A ClassLoader can actually normalize class names a couple of
179 // times, so using "java.lang.Thread" instead of "java/lang/Thread" might work in some
180 // circumstances, but this is incorrect.
181 void CheckClassName(const char* class_name) {
Ian Rogers2d10b202014-05-12 19:15:18 -0700182 if ((class_name == nullptr) || !IsValidJniClassName(class_name)) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700183 JniAbortF(function_name_,
184 "illegal class name '%s'\n"
185 " (should be of the form 'package/Class', [Lpackage/Class;' or '[[B')",
186 class_name);
Elliott Hughesa2501992011-08-26 19:39:54 -0700187 }
188 }
189
190 /*
191 * Verify that the field is of the appropriate type. If the field has an
192 * object type, "java_object" is the object we're trying to assign into it.
193 *
194 * Works for both static and instance fields.
195 */
Ian Rogersef7d42f2014-01-06 12:55:46 -0800196 void CheckFieldType(jvalue value, jfieldID fid, char prim, bool isStatic)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700197 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700198 StackHandleScope<1> hs(Thread::Current());
199 Handle<mirror::ArtField> f(hs.NewHandle(CheckFieldID(fid)));
200 if (f.Get() == nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700201 return;
202 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800203 mirror::Class* field_type = FieldHelper(f).GetType();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700204 if (!field_type->IsPrimitive()) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800205 jobject java_object = value.l;
206 if (java_object != nullptr) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800207 mirror::Object* obj = soa_.Decode<mirror::Object*>(java_object);
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700208 // If java_object is a weak global ref whose referent has been cleared,
209 // obj will be NULL. Otherwise, obj should always be non-NULL
210 // and valid.
Mathieu Chartier590fee92013-09-13 13:46:47 -0700211 if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(obj)) {
Mathieu Chartier128c52c2012-10-16 14:12:41 -0700212 Runtime::Current()->GetHeap()->DumpSpaces();
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700213 JniAbortF(function_name_, "field operation on invalid %s: %p",
214 ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object);
Elliott Hughesa2501992011-08-26 19:39:54 -0700215 return;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700216 } else {
Brian Carlstrom16192862011-09-12 17:50:06 -0700217 if (!obj->InstanceOf(field_type)) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700218 JniAbortF(function_name_, "attempt to set field %s with value of wrong type: %s",
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700219 PrettyField(f.Get()).c_str(), PrettyTypeOf(obj).c_str());
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700220 return;
221 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700222 }
Elliott Hughesa2501992011-08-26 19:39:54 -0700223 }
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700224 } else if (field_type != Runtime::Current()->GetClassLinker()->FindPrimitiveClass(prim)) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700225 JniAbortF(function_name_, "attempt to set field %s with value of wrong type: %c",
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700226 PrettyField(f.Get()).c_str(), prim);
Elliott Hughesa2501992011-08-26 19:39:54 -0700227 return;
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700228 }
229
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700230 if (isStatic != f.Get()->IsStatic()) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700231 if (isStatic) {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700232 JniAbortF(function_name_, "accessing non-static field %s as static",
233 PrettyField(f.Get()).c_str());
Elliott Hughesa2501992011-08-26 19:39:54 -0700234 } else {
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700235 JniAbortF(function_name_, "accessing static field %s as non-static",
236 PrettyField(f.Get()).c_str());
Elliott Hughesa2501992011-08-26 19:39:54 -0700237 }
Elliott Hughesa2501992011-08-26 19:39:54 -0700238 return;
239 }
240 }
241
242 /*
243 * Verify that this instance field ID is valid for this object.
244 *
245 * Assumes "jobj" has already been validated.
246 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700247 void CheckInstanceFieldID(jobject java_object, jfieldID fid)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700248 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800249 mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800250 if (o == nullptr || !Runtime::Current()->GetHeap()->IsValidObjectAddress(o)) {
Mathieu Chartier128c52c2012-10-16 14:12:41 -0700251 Runtime::Current()->GetHeap()->DumpSpaces();
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700252 JniAbortF(function_name_, "field operation on invalid %s: %p",
253 ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object);
Elliott Hughesa2501992011-08-26 19:39:54 -0700254 return;
255 }
256
Brian Carlstromea46f952013-07-30 01:26:50 -0700257 mirror::ArtField* f = CheckFieldID(fid);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800258 if (f == nullptr) {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700259 return;
260 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800261 mirror::Class* c = o->GetClass();
Mathieu Chartier61c5ebc2014-06-05 17:42:53 -0700262 if (c->FindInstanceField(f->GetName(), f->GetTypeDescriptor()) == nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700263 JniAbortF(function_name_, "jfieldID %s not valid for an object of class %s",
264 PrettyField(f).c_str(), PrettyTypeOf(o).c_str());
Elliott Hughesa2501992011-08-26 19:39:54 -0700265 }
266 }
267
268 /*
269 * Verify that the pointer value is non-NULL.
270 */
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700271 void CheckNonNull(const void* ptr) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800272 if (ptr == nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700273 JniAbortF(function_name_, "non-nullable argument was NULL");
Elliott Hughesa2501992011-08-26 19:39:54 -0700274 }
275 }
276
277 /*
278 * Verify that the method's return type matches the type of call.
279 * 'expectedType' will be "L" for all objects, including arrays.
280 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700281 void CheckSig(jmethodID mid, const char* expectedType, bool isStatic)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700282 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700283 mirror::ArtMethod* m = CheckMethodID(mid);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800284 if (m == nullptr) {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700285 return;
286 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700287 if (*expectedType != m->GetShorty()[0]) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700288 JniAbortF(function_name_, "the return type of %s does not match %s",
289 function_name_, PrettyMethod(m).c_str());
290 }
291 if (isStatic != m->IsStatic()) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700292 if (isStatic) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700293 JniAbortF(function_name_, "calling non-static method %s with %s",
294 PrettyMethod(m).c_str(), function_name_);
Elliott Hughesa2501992011-08-26 19:39:54 -0700295 } else {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700296 JniAbortF(function_name_, "calling static method %s with %s",
297 PrettyMethod(m).c_str(), function_name_);
Elliott Hughesa2501992011-08-26 19:39:54 -0700298 }
Elliott Hughesa2501992011-08-26 19:39:54 -0700299 }
300 }
301
302 /*
303 * Verify that this static field ID is valid for this class.
304 *
305 * Assumes "java_class" has already been validated.
306 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700307 void CheckStaticFieldID(jclass java_class, jfieldID fid)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700308 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800309 mirror::Class* c = soa_.Decode<mirror::Class*>(java_class);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800310 mirror::ArtField* f = CheckFieldID(fid);
311 if (f == nullptr) {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700312 return;
313 }
Elliott Hughesa2501992011-08-26 19:39:54 -0700314 if (f->GetDeclaringClass() != c) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700315 JniAbortF(function_name_, "static jfieldID %p not valid for class %s",
316 fid, PrettyClass(c).c_str());
Elliott Hughesa2501992011-08-26 19:39:54 -0700317 }
318 }
319
320 /*
Elliott Hughese84278b2012-03-22 10:06:53 -0700321 * Verify that "mid" is appropriate for "java_class".
Elliott Hughesa2501992011-08-26 19:39:54 -0700322 *
323 * A mismatch isn't dangerous, because the jmethodID defines the class. In
Elliott Hughese84278b2012-03-22 10:06:53 -0700324 * fact, java_class is unused in the implementation. It's best if we don't
Elliott Hughesa2501992011-08-26 19:39:54 -0700325 * allow bad code in the system though.
326 *
Elliott Hughese84278b2012-03-22 10:06:53 -0700327 * Instances of "java_class" must be instances of the method's declaring class.
Elliott Hughesa2501992011-08-26 19:39:54 -0700328 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700329 void CheckStaticMethod(jclass java_class, jmethodID mid)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700330 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800331 mirror::ArtMethod* m = CheckMethodID(mid);
332 if (m == nullptr) {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700333 return;
334 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800335 mirror::Class* c = soa_.Decode<mirror::Class*>(java_class);
Brian Carlstrom67fe2b42013-10-15 18:51:42 -0700336 if (!m->GetDeclaringClass()->IsAssignableFrom(c)) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700337 JniAbortF(function_name_, "can't call static %s on class %s",
338 PrettyMethod(m).c_str(), PrettyClass(c).c_str());
Elliott Hughesa2501992011-08-26 19:39:54 -0700339 }
340 }
341
342 /*
343 * Verify that "mid" is appropriate for "jobj".
344 *
345 * Make sure the object is an instance of the method's declaring class.
346 * (Note the mid might point to a declaration in an interface; this
347 * will be handled automatically by the instanceof check.)
348 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700349 void CheckVirtualMethod(jobject java_object, jmethodID mid)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700350 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800351 mirror::ArtMethod* m = CheckMethodID(mid);
352 if (m == nullptr) {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700353 return;
354 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800355 mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
Elliott Hughesa2501992011-08-26 19:39:54 -0700356 if (!o->InstanceOf(m->GetDeclaringClass())) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700357 JniAbortF(function_name_, "can't call %s on instance of %s",
358 PrettyMethod(m).c_str(), PrettyTypeOf(o).c_str());
Elliott Hughesa2501992011-08-26 19:39:54 -0700359 }
360 }
361
362 /**
363 * The format string is a sequence of the following characters,
364 * and must be followed by arguments of the corresponding types
365 * in the same order.
366 *
367 * Java primitive types:
368 * B - jbyte
369 * C - jchar
370 * D - jdouble
371 * F - jfloat
372 * I - jint
373 * J - jlong
374 * S - jshort
375 * Z - jboolean (shown as true and false)
376 * V - void
377 *
378 * Java reference types:
379 * L - jobject
380 * a - jarray
381 * c - jclass
382 * s - jstring
383 *
384 * JNI types:
385 * b - jboolean (shown as JNI_TRUE and JNI_FALSE)
386 * f - jfieldID
387 * m - jmethodID
388 * p - void*
389 * r - jint (for release mode arguments)
Elliott Hughes78090d12011-10-07 14:31:47 -0700390 * u - const char* (Modified UTF-8)
Elliott Hughesa2501992011-08-26 19:39:54 -0700391 * z - jsize (for lengths; use i if negative values are okay)
392 * v - JavaVM*
393 * E - JNIEnv*
394 * . - no argument; just print "..." (used for varargs JNI calls)
395 *
396 * Use the kFlag_NullableUtf flag where 'u' field(s) are nullable.
397 */
Brian Carlstromdf629502013-07-17 22:39:56 -0700398 void Check(bool entry, const char* fmt0, ...) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700399 va_list ap;
400
Ian Rogersef7d42f2014-01-06 12:55:46 -0800401 mirror::ArtMethod* traceMethod = nullptr;
Ian Rogers9365f582013-04-19 09:55:42 -0700402 if (has_method_ && (!soa_.Vm()->trace.empty() || VLOG_IS_ON(third_party_jni))) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700403 // We need to guard some of the invocation interface's calls: a bad caller might
404 // use DetachCurrentThread or GetEnv on a thread that's not yet attached.
Elliott Hughesa0957642011-09-02 14:27:33 -0700405 Thread* self = Thread::Current();
Ian Rogersef7d42f2014-01-06 12:55:46 -0800406 if ((flags_ & kFlag_Invocation) == 0 || self != nullptr) {
407 traceMethod = self->GetCurrentMethod(nullptr);
Elliott Hughesa2501992011-08-26 19:39:54 -0700408 }
409 }
Elliott Hughesa0957642011-09-02 14:27:33 -0700410
Ian Rogersef7d42f2014-01-06 12:55:46 -0800411 if (((flags_ & kFlag_ForceTrace) != 0) ||
412 (traceMethod != nullptr && ShouldTrace(soa_.Vm(), traceMethod))) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700413 va_start(ap, fmt0);
414 std::string msg;
415 for (const char* fmt = fmt0; *fmt;) {
416 char ch = *fmt++;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700417 if (ch == 'B') { // jbyte
Elliott Hughesa2501992011-08-26 19:39:54 -0700418 jbyte b = va_arg(ap, int);
419 if (b >= 0 && b < 10) {
420 StringAppendF(&msg, "%d", b);
421 } else {
422 StringAppendF(&msg, "%#x (%d)", b, b);
423 }
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700424 } else if (ch == 'C') { // jchar
Elliott Hughesa2501992011-08-26 19:39:54 -0700425 jchar c = va_arg(ap, int);
426 if (c < 0x7f && c >= ' ') {
427 StringAppendF(&msg, "U+%x ('%c')", c, c);
428 } else {
429 StringAppendF(&msg, "U+%x", c);
430 }
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700431 } else if (ch == 'F' || ch == 'D') { // jfloat, jdouble
Elliott Hughesa2501992011-08-26 19:39:54 -0700432 StringAppendF(&msg, "%g", va_arg(ap, double));
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700433 } else if (ch == 'I' || ch == 'S') { // jint, jshort
Elliott Hughesa2501992011-08-26 19:39:54 -0700434 StringAppendF(&msg, "%d", va_arg(ap, int));
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700435 } else if (ch == 'J') { // jlong
Ian Rogersef7d42f2014-01-06 12:55:46 -0800436 StringAppendF(&msg, "%" PRId64, va_arg(ap, jlong));
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700437 } else if (ch == 'Z') { // jboolean
Elliott Hughesa2501992011-08-26 19:39:54 -0700438 StringAppendF(&msg, "%s", va_arg(ap, int) ? "true" : "false");
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700439 } else if (ch == 'V') { // void
Elliott Hughesa2501992011-08-26 19:39:54 -0700440 msg += "void";
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700441 } else if (ch == 'v') { // JavaVM*
Elliott Hughesa2501992011-08-26 19:39:54 -0700442 JavaVM* vm = va_arg(ap, JavaVM*);
443 StringAppendF(&msg, "(JavaVM*)%p", vm);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700444 } else if (ch == 'E') { // JNIEnv*
Elliott Hughesa2501992011-08-26 19:39:54 -0700445 JNIEnv* env = va_arg(ap, JNIEnv*);
446 StringAppendF(&msg, "(JNIEnv*)%p", env);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700447 } else if (ch == 'L' || ch == 'a' || ch == 's') { // jobject, jarray, jstring
Elliott Hughesa2501992011-08-26 19:39:54 -0700448 // For logging purposes, these are identical.
449 jobject o = va_arg(ap, jobject);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800450 if (o == nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700451 msg += "NULL";
452 } else {
453 StringAppendF(&msg, "%p", o);
454 }
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700455 } else if (ch == 'b') { // jboolean (JNI-style)
Elliott Hughesa2501992011-08-26 19:39:54 -0700456 jboolean b = va_arg(ap, int);
457 msg += (b ? "JNI_TRUE" : "JNI_FALSE");
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700458 } else if (ch == 'c') { // jclass
Elliott Hughesa2501992011-08-26 19:39:54 -0700459 jclass jc = va_arg(ap, jclass);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800460 mirror::Class* c = reinterpret_cast<mirror::Class*>(Thread::Current()->DecodeJObject(jc));
Ian Rogersef7d42f2014-01-06 12:55:46 -0800461 if (c == nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700462 msg += "NULL";
Mathieu Chartier590fee92013-09-13 13:46:47 -0700463 } else if (c == kInvalidIndirectRefObject ||
464 !Runtime::Current()->GetHeap()->IsValidObjectAddress(c)) {
Elliott Hughes485cac42011-12-09 17:49:35 -0800465 StringAppendF(&msg, "INVALID POINTER:%p", jc);
466 } else if (!c->IsClass()) {
467 msg += "INVALID NON-CLASS OBJECT OF TYPE:" + PrettyTypeOf(c);
Elliott Hughesa2501992011-08-26 19:39:54 -0700468 } else {
Elliott Hughes54e7df12011-09-16 11:47:04 -0700469 msg += PrettyClass(c);
Elliott Hughesa2501992011-08-26 19:39:54 -0700470 if (!entry) {
471 StringAppendF(&msg, " (%p)", jc);
472 }
473 }
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700474 } else if (ch == 'f') { // jfieldID
Elliott Hughesa2501992011-08-26 19:39:54 -0700475 jfieldID fid = va_arg(ap, jfieldID);
Brian Carlstromea46f952013-07-30 01:26:50 -0700476 mirror::ArtField* f = reinterpret_cast<mirror::ArtField*>(fid);
Elliott Hughesa2501992011-08-26 19:39:54 -0700477 msg += PrettyField(f);
478 if (!entry) {
479 StringAppendF(&msg, " (%p)", fid);
480 }
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700481 } else if (ch == 'z') { // non-negative jsize
Elliott Hughesa2501992011-08-26 19:39:54 -0700482 // You might expect jsize to be size_t, but it's not; it's the same as jint.
483 // We only treat this specially so we can do the non-negative check.
484 // TODO: maybe this wasn't worth it?
485 jint i = va_arg(ap, jint);
486 StringAppendF(&msg, "%d", i);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700487 } else if (ch == 'm') { // jmethodID
Elliott Hughesa2501992011-08-26 19:39:54 -0700488 jmethodID mid = va_arg(ap, jmethodID);
Brian Carlstromea46f952013-07-30 01:26:50 -0700489 mirror::ArtMethod* m = reinterpret_cast<mirror::ArtMethod*>(mid);
Elliott Hughesa2501992011-08-26 19:39:54 -0700490 msg += PrettyMethod(m);
491 if (!entry) {
492 StringAppendF(&msg, " (%p)", mid);
493 }
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700494 } else if (ch == 'p') { // void* ("pointer")
Elliott Hughesa2501992011-08-26 19:39:54 -0700495 void* p = va_arg(ap, void*);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800496 if (p == nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700497 msg += "NULL";
498 } else {
499 StringAppendF(&msg, "(void*) %p", p);
500 }
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700501 } else if (ch == 'r') { // jint (release mode)
Elliott Hughesa2501992011-08-26 19:39:54 -0700502 jint releaseMode = va_arg(ap, jint);
503 if (releaseMode == 0) {
504 msg += "0";
505 } else if (releaseMode == JNI_ABORT) {
506 msg += "JNI_ABORT";
507 } else if (releaseMode == JNI_COMMIT) {
508 msg += "JNI_COMMIT";
509 } else {
510 StringAppendF(&msg, "invalid release mode %d", releaseMode);
511 }
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700512 } else if (ch == 'u') { // const char* (Modified UTF-8)
Elliott Hughesa2501992011-08-26 19:39:54 -0700513 const char* utf = va_arg(ap, const char*);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800514 if (utf == nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700515 msg += "NULL";
516 } else {
517 StringAppendF(&msg, "\"%s\"", utf);
518 }
519 } else if (ch == '.') {
520 msg += "...";
521 } else {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700522 JniAbortF(function_name_, "unknown trace format specifier: %c", ch);
Elliott Hughesa2501992011-08-26 19:39:54 -0700523 return;
524 }
525 if (*fmt) {
526 StringAppendF(&msg, ", ");
527 }
528 }
529 va_end(ap);
530
Elliott Hughes485cac42011-12-09 17:49:35 -0800531 if ((flags_ & kFlag_ForceTrace) != 0) {
532 LOG(INFO) << "JNI: call to " << function_name_ << "(" << msg << ")";
533 } else if (entry) {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700534 if (has_method_) {
Elliott Hughesa0957642011-09-02 14:27:33 -0700535 std::string methodName(PrettyMethod(traceMethod, false));
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700536 LOG(INFO) << "JNI: " << methodName << " -> " << function_name_ << "(" << msg << ")";
537 indent_ = methodName.size() + 1;
Elliott Hughesa2501992011-08-26 19:39:54 -0700538 } else {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700539 LOG(INFO) << "JNI: -> " << function_name_ << "(" << msg << ")";
540 indent_ = 0;
Elliott Hughesa2501992011-08-26 19:39:54 -0700541 }
542 } else {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700543 LOG(INFO) << StringPrintf("JNI: %*s<- %s returned %s", indent_, "", function_name_, msg.c_str());
Elliott Hughesa2501992011-08-26 19:39:54 -0700544 }
545 }
546
547 // We always do the thorough checks on entry, and never on exit...
548 if (entry) {
549 va_start(ap, fmt0);
550 for (const char* fmt = fmt0; *fmt; ++fmt) {
551 char ch = *fmt;
552 if (ch == 'a') {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700553 CheckArray(va_arg(ap, jarray));
Elliott Hughesa2501992011-08-26 19:39:54 -0700554 } else if (ch == 'c') {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700555 CheckInstance(kClass, va_arg(ap, jclass));
Elliott Hughesa2501992011-08-26 19:39:54 -0700556 } else if (ch == 'L') {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700557 CheckObject(va_arg(ap, jobject));
Elliott Hughesa2501992011-08-26 19:39:54 -0700558 } else if (ch == 'r') {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700559 CheckReleaseMode(va_arg(ap, jint));
Elliott Hughesa2501992011-08-26 19:39:54 -0700560 } else if (ch == 's') {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700561 CheckInstance(kString, va_arg(ap, jstring));
Elliott Hughesa2501992011-08-26 19:39:54 -0700562 } else if (ch == 'u') {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700563 if ((flags_ & kFlag_Release) != 0) {
564 CheckNonNull(va_arg(ap, const char*));
Elliott Hughesa2501992011-08-26 19:39:54 -0700565 } else {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700566 bool nullable = ((flags_ & kFlag_NullableUtf) != 0);
567 CheckUtfString(va_arg(ap, const char*), nullable);
Elliott Hughesa2501992011-08-26 19:39:54 -0700568 }
569 } else if (ch == 'z') {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700570 CheckLengthPositive(va_arg(ap, jsize));
Ian Rogersef7d42f2014-01-06 12:55:46 -0800571 } else if (strchr("BCISZbfmpEv", ch) != nullptr) {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700572 va_arg(ap, uint32_t); // Skip this argument.
Elliott Hughesa2501992011-08-26 19:39:54 -0700573 } else if (ch == 'D' || ch == 'F') {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700574 va_arg(ap, double); // Skip this argument.
Elliott Hughesa2501992011-08-26 19:39:54 -0700575 } else if (ch == 'J') {
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700576 va_arg(ap, uint64_t); // Skip this argument.
Elliott Hughesa2501992011-08-26 19:39:54 -0700577 } else if (ch == '.') {
578 } else {
Elliott Hughes3d30d9b2011-12-07 17:35:48 -0800579 LOG(FATAL) << "Unknown check format specifier: " << ch;
Elliott Hughesa2501992011-08-26 19:39:54 -0700580 }
581 }
582 va_end(ap);
583 }
584 }
585
Elliott Hughesa92853e2012-02-07 16:09:27 -0800586 enum InstanceKind {
587 kClass,
Elliott Hughes0f3c5532012-03-30 14:51:51 -0700588 kDirectByteBuffer,
589 kObject,
590 kString,
591 kThrowable,
Elliott Hughesa92853e2012-02-07 16:09:27 -0800592 };
593
594 /*
595 * Verify that "jobj" is a valid non-NULL object reference, and points to
596 * an instance of expectedClass.
597 *
598 * Because we're looking at an object on the GC heap, we have to switch
599 * to "running" mode before doing the checks.
600 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700601 bool CheckInstance(InstanceKind kind, jobject java_object)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700602 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800603 const char* what = nullptr;
Elliott Hughesa92853e2012-02-07 16:09:27 -0800604 switch (kind) {
605 case kClass:
606 what = "jclass";
607 break;
608 case kDirectByteBuffer:
609 what = "direct ByteBuffer";
610 break;
611 case kObject:
612 what = "jobject";
613 break;
614 case kString:
615 what = "jstring";
616 break;
617 case kThrowable:
618 what = "jthrowable";
619 break;
620 default:
Elliott Hughes7b9d9962012-04-20 18:48:18 -0700621 LOG(FATAL) << "Unknown kind " << static_cast<int>(kind);
Elliott Hughesa92853e2012-02-07 16:09:27 -0800622 }
623
Ian Rogersef7d42f2014-01-06 12:55:46 -0800624 if (java_object == nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700625 JniAbortF(function_name_, "%s received null %s", function_name_, what);
Elliott Hughesa92853e2012-02-07 16:09:27 -0800626 return false;
627 }
628
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800629 mirror::Object* obj = soa_.Decode<mirror::Object*>(java_object);
Mathieu Chartier590fee92013-09-13 13:46:47 -0700630 if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(obj)) {
Mathieu Chartier128c52c2012-10-16 14:12:41 -0700631 Runtime::Current()->GetHeap()->DumpSpaces();
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700632 JniAbortF(function_name_, "%s is an invalid %s: %p (%p)",
633 what, ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object, obj);
Elliott Hughesa92853e2012-02-07 16:09:27 -0800634 return false;
635 }
636
637 bool okay = true;
638 switch (kind) {
639 case kClass:
640 okay = obj->IsClass();
641 break;
642 case kDirectByteBuffer:
643 UNIMPLEMENTED(FATAL);
644 break;
645 case kString:
646 okay = obj->GetClass()->IsStringClass();
647 break;
648 case kThrowable:
649 okay = obj->GetClass()->IsThrowableClass();
650 break;
651 case kObject:
652 break;
653 }
654 if (!okay) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700655 JniAbortF(function_name_, "%s has wrong type: %s", what, PrettyTypeOf(obj).c_str());
Elliott Hughesa92853e2012-02-07 16:09:27 -0800656 return false;
657 }
658
659 return true;
660 }
661
Elliott Hughesba8eee12012-01-24 20:25:24 -0800662 private:
Elliott Hughes81ff3182012-03-23 20:35:56 -0700663 // Set "has_method" to true if we have a valid thread with a method pointer.
664 // We won't have one before attaching a thread, after detaching a thread, or
665 // when shutting down the runtime.
Ian Rogers365c1022012-06-22 15:05:28 -0700666 void Init(int flags, const char* functionName, bool has_method) {
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700667 flags_ = flags;
668 function_name_ = functionName;
Elliott Hughes81ff3182012-03-23 20:35:56 -0700669 has_method_ = has_method;
Elliott Hughesa2501992011-08-26 19:39:54 -0700670 }
671
672 /*
673 * Verify that "array" is non-NULL and points to an Array object.
674 *
675 * Since we're dealing with objects, switch to "running" mode.
676 */
Ian Rogersb726dcb2012-09-05 08:57:23 -0700677 void CheckArray(jarray java_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800678 if (java_array == nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700679 JniAbortF(function_name_, "jarray was NULL");
Elliott Hughesa2501992011-08-26 19:39:54 -0700680 return;
681 }
682
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800683 mirror::Array* a = soa_.Decode<mirror::Array*>(java_array);
Mathieu Chartier590fee92013-09-13 13:46:47 -0700684 if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(a)) {
Mathieu Chartier128c52c2012-10-16 14:12:41 -0700685 Runtime::Current()->GetHeap()->DumpSpaces();
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700686 JniAbortF(function_name_, "jarray is an invalid %s: %p (%p)",
687 ToStr<IndirectRefKind>(GetIndirectRefKind(java_array)).c_str(), java_array, a);
Elliott Hughesa2501992011-08-26 19:39:54 -0700688 } else if (!a->IsArrayInstance()) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700689 JniAbortF(function_name_, "jarray argument has non-array type: %s", PrettyTypeOf(a).c_str());
Elliott Hughesa2501992011-08-26 19:39:54 -0700690 }
691 }
692
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700693 void CheckLengthPositive(jsize length) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700694 if (length < 0) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700695 JniAbortF(function_name_, "negative jsize: %d", length);
Elliott Hughesa2501992011-08-26 19:39:54 -0700696 }
697 }
698
Brian Carlstromea46f952013-07-30 01:26:50 -0700699 mirror::ArtField* CheckFieldID(jfieldID fid) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800700 if (fid == nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700701 JniAbortF(function_name_, "jfieldID was NULL");
Ian Rogersef7d42f2014-01-06 12:55:46 -0800702 return nullptr;
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700703 }
Brian Carlstromea46f952013-07-30 01:26:50 -0700704 mirror::ArtField* f = soa_.DecodeField(fid);
Mathieu Chartier590fee92013-09-13 13:46:47 -0700705 if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(f) || !f->IsArtField()) {
Mathieu Chartier128c52c2012-10-16 14:12:41 -0700706 Runtime::Current()->GetHeap()->DumpSpaces();
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700707 JniAbortF(function_name_, "invalid jfieldID: %p", fid);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800708 return nullptr;
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700709 }
710 return f;
711 }
712
Brian Carlstromea46f952013-07-30 01:26:50 -0700713 mirror::ArtMethod* CheckMethodID(jmethodID mid) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800714 if (mid == nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700715 JniAbortF(function_name_, "jmethodID was NULL");
Ian Rogersef7d42f2014-01-06 12:55:46 -0800716 return nullptr;
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700717 }
Brian Carlstromea46f952013-07-30 01:26:50 -0700718 mirror::ArtMethod* m = soa_.DecodeMethod(mid);
Mathieu Chartier590fee92013-09-13 13:46:47 -0700719 if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(m) || !m->IsArtMethod()) {
Mathieu Chartier128c52c2012-10-16 14:12:41 -0700720 Runtime::Current()->GetHeap()->DumpSpaces();
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700721 JniAbortF(function_name_, "invalid jmethodID: %p", mid);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800722 return nullptr;
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700723 }
724 return m;
725 }
726
Elliott Hughesa2501992011-08-26 19:39:54 -0700727 /*
728 * Verify that "jobj" is a valid object, and that it's an object that JNI
729 * is allowed to know about. We allow NULL references.
730 *
731 * Switches to "running" mode before performing checks.
732 */
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700733 void CheckObject(jobject java_object)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700734 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800735 if (java_object == nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700736 return;
737 }
738
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800739 mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
Mathieu Chartier590fee92013-09-13 13:46:47 -0700740 if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(o)) {
Mathieu Chartier128c52c2012-10-16 14:12:41 -0700741 Runtime::Current()->GetHeap()->DumpSpaces();
Elliott Hughesc5bfa8f2011-08-30 14:32:49 -0700742 // TODO: when we remove work_around_app_jni_bugs, this should be impossible.
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700743 JniAbortF(function_name_, "native code passing in reference to invalid %s: %p",
744 ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), java_object);
Elliott Hughesa2501992011-08-26 19:39:54 -0700745 }
746 }
747
748 /*
749 * Verify that the "mode" argument passed to a primitive array Release
750 * function is one of the valid values.
751 */
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700752 void CheckReleaseMode(jint mode) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700753 if (mode != 0 && mode != JNI_COMMIT && mode != JNI_ABORT) {
Elliott Hughes96a98872012-12-19 14:21:15 -0800754 JniAbortF(function_name_, "unknown value for release mode: %d", mode);
Elliott Hughesa2501992011-08-26 19:39:54 -0700755 }
756 }
757
Ian Rogersb726dcb2012-09-05 08:57:23 -0700758 void CheckThread(int flags) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700759 Thread* self = Thread::Current();
Ian Rogersef7d42f2014-01-06 12:55:46 -0800760 if (self == nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700761 JniAbortF(function_name_, "a thread (tid %d) is making JNI calls without being attached", GetTid());
Elliott Hughesa2501992011-08-26 19:39:54 -0700762 return;
763 }
764
765 // Get the *correct* JNIEnv by going through our TLS pointer.
766 JNIEnvExt* threadEnv = self->GetJniEnv();
767
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700768 // Verify that the current thread is (a) attached and (b) associated with
769 // this particular instance of JNIEnv.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700770 if (soa_.Env() != threadEnv) {
Ian Rogers987560f2014-04-22 11:42:59 -0700771 JniAbortF(function_name_, "thread %s using JNIEnv* from thread %s",
772 ToStr<Thread>(*self).c_str(), ToStr<Thread>(*soa_.Self()).c_str());
773 return;
Elliott Hughesa2501992011-08-26 19:39:54 -0700774 }
775
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700776 // Verify that, if this thread previously made a critical "get" call, we
777 // do the corresponding "release" call before we try anything else.
Elliott Hughesa2501992011-08-26 19:39:54 -0700778 switch (flags & kFlag_CritMask) {
779 case kFlag_CritOkay: // okay to call this method
780 break;
781 case kFlag_CritBad: // not okay to call
782 if (threadEnv->critical) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700783 JniAbortF(function_name_, "thread %s using JNI after critical get", ToStr<Thread>(*self).c_str());
Elliott Hughesa2501992011-08-26 19:39:54 -0700784 return;
785 }
786 break;
787 case kFlag_CritGet: // this is a "get" call
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700788 // Don't check here; we allow nested gets.
Elliott Hughesa2501992011-08-26 19:39:54 -0700789 threadEnv->critical++;
790 break;
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700791 case kFlag_CritRelease: // this is a "release" call
Elliott Hughesa2501992011-08-26 19:39:54 -0700792 threadEnv->critical--;
793 if (threadEnv->critical < 0) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700794 JniAbortF(function_name_, "thread %s called too many critical releases", ToStr<Thread>(*self).c_str());
Elliott Hughesa2501992011-08-26 19:39:54 -0700795 return;
796 }
797 break;
798 default:
Elliott Hughes3d30d9b2011-12-07 17:35:48 -0800799 LOG(FATAL) << "Bad flags (internal error): " << flags;
Elliott Hughesa2501992011-08-26 19:39:54 -0700800 }
801
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700802 // Verify that, if an exception has been raised, the native code doesn't
803 // make any JNI calls other than the Exception* methods.
Elliott Hughesa2501992011-08-26 19:39:54 -0700804 if ((flags & kFlag_ExcepOkay) == 0 && self->IsExceptionPending()) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800805 ThrowLocation throw_location;
806 mirror::Throwable* exception = self->GetException(&throw_location);
807 std::string type(PrettyTypeOf(exception));
Elliott Hughes8e4d3ed2013-09-03 17:41:50 -0700808 JniAbortF(function_name_, "JNI %s called with pending exception '%s' thrown in %s",
809 function_name_, type.c_str(), throw_location.Dump().c_str());
Elliott Hughesa2501992011-08-26 19:39:54 -0700810 return;
811 }
812 }
813
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700814 // Verifies that "bytes" points to valid Modified UTF-8 data.
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700815 void CheckUtfString(const char* bytes, bool nullable) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800816 if (bytes == nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700817 if (!nullable) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700818 JniAbortF(function_name_, "non-nullable const char* was NULL");
Elliott Hughesa2501992011-08-26 19:39:54 -0700819 return;
820 }
821 return;
822 }
823
Ian Rogersef7d42f2014-01-06 12:55:46 -0800824 const char* errorKind = nullptr;
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700825 uint8_t utf8 = CheckUtfBytes(bytes, &errorKind);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800826 if (errorKind != nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700827 JniAbortF(function_name_,
828 "input is not valid Modified UTF-8: illegal %s byte %#x\n"
829 " string: '%s'", errorKind, utf8, bytes);
Elliott Hughesa2501992011-08-26 19:39:54 -0700830 return;
831 }
832 }
833
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700834 static uint8_t CheckUtfBytes(const char* bytes, const char** errorKind) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700835 while (*bytes != '\0') {
836 uint8_t utf8 = *(bytes++);
837 // Switch on the high four bits.
838 switch (utf8 >> 4) {
839 case 0x00:
840 case 0x01:
841 case 0x02:
842 case 0x03:
843 case 0x04:
844 case 0x05:
845 case 0x06:
846 case 0x07:
847 // Bit pattern 0xxx. No need for any extra bytes.
848 break;
849 case 0x08:
850 case 0x09:
851 case 0x0a:
852 case 0x0b:
853 case 0x0f:
854 /*
855 * Bit pattern 10xx or 1111, which are illegal start bytes.
856 * Note: 1111 is valid for normal UTF-8, but not the
Elliott Hughes78090d12011-10-07 14:31:47 -0700857 * Modified UTF-8 used here.
Elliott Hughesa2501992011-08-26 19:39:54 -0700858 */
859 *errorKind = "start";
860 return utf8;
861 case 0x0e:
862 // Bit pattern 1110, so there are two additional bytes.
863 utf8 = *(bytes++);
864 if ((utf8 & 0xc0) != 0x80) {
865 *errorKind = "continuation";
866 return utf8;
867 }
868 // Fall through to take care of the final byte.
869 case 0x0c:
870 case 0x0d:
871 // Bit pattern 110x, so there is one additional byte.
872 utf8 = *(bytes++);
873 if ((utf8 & 0xc0) != 0x80) {
874 *errorKind = "continuation";
875 return utf8;
876 }
877 break;
878 }
879 }
880 return 0;
881 }
882
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700883 const ScopedObjectAccess soa_;
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700884 const char* function_name_;
885 int flags_;
886 bool has_method_;
Elliott Hughes92cb4982011-12-16 16:57:28 -0800887 int indent_;
Elliott Hughesa2501992011-08-26 19:39:54 -0700888
889 DISALLOW_COPY_AND_ASSIGN(ScopedCheck);
890};
891
892#define CHECK_JNI_ENTRY(flags, types, args...) \
893 ScopedCheck sc(env, flags, __FUNCTION__); \
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700894 sc.Check(true, types, ##args)
Elliott Hughesa2501992011-08-26 19:39:54 -0700895
896#define CHECK_JNI_EXIT(type, exp) ({ \
Mathieu Chartier9b3c3cd2013-08-12 17:41:54 -0700897 auto _rc = (exp); \
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700898 sc.Check(false, type, _rc); \
Elliott Hughesa2501992011-08-26 19:39:54 -0700899 _rc; })
900#define CHECK_JNI_EXIT_VOID() \
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700901 sc.Check(false, "V")
Elliott Hughesa2501992011-08-26 19:39:54 -0700902
903/*
904 * ===========================================================================
905 * Guarded arrays
906 * ===========================================================================
907 */
908
909#define kGuardLen 512 /* must be multiple of 2 */
910#define kGuardPattern 0xd5e3 /* uncommon values; d5e3d5e3 invalid addr */
911#define kGuardMagic 0xffd5aa96
912
913/* this gets tucked in at the start of the buffer; struct size must be even */
914struct GuardedCopy {
915 uint32_t magic;
916 uLong adler;
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700917 size_t original_length;
918 const void* original_ptr;
Elliott Hughesa2501992011-08-26 19:39:54 -0700919
920 /* find the GuardedCopy given the pointer into the "live" data */
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700921 static inline const GuardedCopy* FromData(const void* dataBuf) {
922 return reinterpret_cast<const GuardedCopy*>(ActualBuffer(dataBuf));
Elliott Hughesa2501992011-08-26 19:39:54 -0700923 }
924
925 /*
926 * Create an over-sized buffer to hold the contents of "buf". Copy it in,
927 * filling in the area around it with guard data.
928 *
929 * We use a 16-bit pattern to make a rogue memset less likely to elude us.
930 */
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700931 static void* Create(const void* buf, size_t len, bool modOkay) {
932 size_t newLen = ActualLength(len);
933 uint8_t* newBuf = DebugAlloc(newLen);
Elliott Hughesa2501992011-08-26 19:39:54 -0700934
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700935 // Fill it in with a pattern.
Elliott Hughesba8eee12012-01-24 20:25:24 -0800936 uint16_t* pat = reinterpret_cast<uint16_t*>(newBuf);
Elliott Hughesa2501992011-08-26 19:39:54 -0700937 for (size_t i = 0; i < newLen / 2; i++) {
938 *pat++ = kGuardPattern;
939 }
940
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700941 // Copy the data in; note "len" could be zero.
Elliott Hughesa2501992011-08-26 19:39:54 -0700942 memcpy(newBuf + kGuardLen / 2, buf, len);
943
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700944 // If modification is not expected, grab a checksum.
Elliott Hughesa2501992011-08-26 19:39:54 -0700945 uLong adler = 0;
946 if (!modOkay) {
947 adler = adler32(0L, Z_NULL, 0);
Elliott Hughesba8eee12012-01-24 20:25:24 -0800948 adler = adler32(adler, reinterpret_cast<const Bytef*>(buf), len);
949 *reinterpret_cast<uLong*>(newBuf) = adler;
Elliott Hughesa2501992011-08-26 19:39:54 -0700950 }
951
952 GuardedCopy* pExtra = reinterpret_cast<GuardedCopy*>(newBuf);
953 pExtra->magic = kGuardMagic;
954 pExtra->adler = adler;
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700955 pExtra->original_ptr = buf;
956 pExtra->original_length = len;
Elliott Hughesa2501992011-08-26 19:39:54 -0700957
958 return newBuf + kGuardLen / 2;
959 }
960
961 /*
962 * Free up the guard buffer, scrub it, and return the original pointer.
963 */
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700964 static void* Destroy(void* dataBuf) {
965 const GuardedCopy* pExtra = GuardedCopy::FromData(dataBuf);
Elliott Hughesba8eee12012-01-24 20:25:24 -0800966 void* original_ptr = const_cast<void*>(pExtra->original_ptr);
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700967 size_t len = pExtra->original_length;
968 DebugFree(dataBuf, len);
969 return original_ptr;
Elliott Hughesa2501992011-08-26 19:39:54 -0700970 }
971
972 /*
973 * Verify the guard area and, if "modOkay" is false, that the data itself
974 * has not been altered.
975 *
976 * The caller has already checked that "dataBuf" is non-NULL.
977 */
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700978 static void Check(const char* functionName, const void* dataBuf, bool modOkay) {
Elliott Hughesa2501992011-08-26 19:39:54 -0700979 static const uint32_t kMagicCmp = kGuardMagic;
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700980 const uint8_t* fullBuf = ActualBuffer(dataBuf);
981 const GuardedCopy* pExtra = GuardedCopy::FromData(dataBuf);
Elliott Hughesa2501992011-08-26 19:39:54 -0700982
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700983 // Before we do anything with "pExtra", check the magic number. We
984 // do the check with memcmp rather than "==" in case the pointer is
985 // unaligned. If it points to completely bogus memory we're going
986 // to crash, but there's no easy way around that.
Elliott Hughesa2501992011-08-26 19:39:54 -0700987 if (memcmp(&pExtra->magic, &kMagicCmp, 4) != 0) {
988 uint8_t buf[4];
989 memcpy(buf, &pExtra->magic, 4);
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700990 JniAbortF(functionName,
991 "guard magic does not match (found 0x%02x%02x%02x%02x) -- incorrect data pointer %p?",
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700992 buf[3], buf[2], buf[1], buf[0], dataBuf); // Assumes little-endian.
Elliott Hughesa2501992011-08-26 19:39:54 -0700993 }
994
Elliott Hughes32ae6e32011-09-27 10:46:50 -0700995 size_t len = pExtra->original_length;
Elliott Hughesa2501992011-08-26 19:39:54 -0700996
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700997 // Check bottom half of guard; skip over optional checksum storage.
Elliott Hughesba8eee12012-01-24 20:25:24 -0800998 const uint16_t* pat = reinterpret_cast<const uint16_t*>(fullBuf);
Elliott Hughesa2501992011-08-26 19:39:54 -0700999 for (size_t i = sizeof(GuardedCopy) / 2; i < (kGuardLen / 2 - sizeof(GuardedCopy)) / 2; i++) {
1000 if (pat[i] != kGuardPattern) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08001001 JniAbortF(functionName, "guard pattern(1) disturbed at %p +%zd", fullBuf, i*2);
Elliott Hughesa2501992011-08-26 19:39:54 -07001002 }
1003 }
1004
1005 int offset = kGuardLen / 2 + len;
1006 if (offset & 0x01) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001007 // Odd byte; expected value depends on endian.
Elliott Hughesa2501992011-08-26 19:39:54 -07001008 const uint16_t patSample = kGuardPattern;
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001009 uint8_t expected_byte = reinterpret_cast<const uint8_t*>(&patSample)[1];
1010 if (fullBuf[offset] != expected_byte) {
1011 JniAbortF(functionName, "guard pattern disturbed in odd byte after %p +%d 0x%02x 0x%02x",
1012 fullBuf, offset, fullBuf[offset], expected_byte);
Elliott Hughesa2501992011-08-26 19:39:54 -07001013 }
1014 offset++;
1015 }
1016
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001017 // Check top half of guard.
Elliott Hughesba8eee12012-01-24 20:25:24 -08001018 pat = reinterpret_cast<const uint16_t*>(fullBuf + offset);
Elliott Hughesa2501992011-08-26 19:39:54 -07001019 for (size_t i = 0; i < kGuardLen / 4; i++) {
1020 if (pat[i] != kGuardPattern) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08001021 JniAbortF(functionName, "guard pattern(2) disturbed at %p +%zd", fullBuf, offset + i*2);
Elliott Hughesa2501992011-08-26 19:39:54 -07001022 }
1023 }
1024
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001025 // If modification is not expected, verify checksum. Strictly speaking
1026 // this is wrong: if we told the client that we made a copy, there's no
1027 // reason they can't alter the buffer.
Elliott Hughesa2501992011-08-26 19:39:54 -07001028 if (!modOkay) {
1029 uLong adler = adler32(0L, Z_NULL, 0);
1030 adler = adler32(adler, (const Bytef*)dataBuf, len);
1031 if (pExtra->adler != adler) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001032 JniAbortF(functionName, "buffer modified (0x%08lx vs 0x%08lx) at address %p",
1033 pExtra->adler, adler, dataBuf);
Elliott Hughesa2501992011-08-26 19:39:54 -07001034 }
1035 }
1036 }
1037
1038 private:
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001039 static uint8_t* DebugAlloc(size_t len) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08001040 void* result = mmap(nullptr, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
Elliott Hughesa2501992011-08-26 19:39:54 -07001041 if (result == MAP_FAILED) {
1042 PLOG(FATAL) << "GuardedCopy::create mmap(" << len << ") failed";
1043 }
1044 return reinterpret_cast<uint8_t*>(result);
1045 }
1046
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001047 static void DebugFree(void* dataBuf, size_t len) {
1048 uint8_t* fullBuf = ActualBuffer(dataBuf);
1049 size_t totalByteCount = ActualLength(len);
Elliott Hughesa2501992011-08-26 19:39:54 -07001050 // TODO: we could mprotect instead, and keep the allocation around for a while.
1051 // This would be even more expensive, but it might catch more errors.
1052 // if (mprotect(fullBuf, totalByteCount, PROT_NONE) != 0) {
Elliott Hughes7b9d9962012-04-20 18:48:18 -07001053 // PLOG(WARNING) << "mprotect(PROT_NONE) failed";
Elliott Hughesa2501992011-08-26 19:39:54 -07001054 // }
1055 if (munmap(fullBuf, totalByteCount) != 0) {
Elliott Hughesba8eee12012-01-24 20:25:24 -08001056 PLOG(FATAL) << "munmap(" << reinterpret_cast<void*>(fullBuf) << ", " << totalByteCount << ") failed";
Elliott Hughesa2501992011-08-26 19:39:54 -07001057 }
1058 }
1059
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001060 static const uint8_t* ActualBuffer(const void* dataBuf) {
Elliott Hughesa2501992011-08-26 19:39:54 -07001061 return reinterpret_cast<const uint8_t*>(dataBuf) - kGuardLen / 2;
1062 }
1063
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001064 static uint8_t* ActualBuffer(void* dataBuf) {
Elliott Hughesa2501992011-08-26 19:39:54 -07001065 return reinterpret_cast<uint8_t*>(dataBuf) - kGuardLen / 2;
1066 }
1067
1068 // Underlying length of a user allocation of 'length' bytes.
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001069 static size_t ActualLength(size_t length) {
Elliott Hughesa2501992011-08-26 19:39:54 -07001070 return (length + kGuardLen + 1) & ~0x01;
1071 }
1072};
1073
1074/*
1075 * Create a guarded copy of a primitive array. Modifications to the copied
1076 * data are allowed. Returns a pointer to the copied data.
1077 */
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001078static void* CreateGuardedPACopy(JNIEnv* env, const jarray java_array, jboolean* isCopy) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001079 ScopedObjectAccess soa(env);
Elliott Hughesa2501992011-08-26 19:39:54 -07001080
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001081 mirror::Array* a = soa.Decode<mirror::Array*>(java_array);
Ian Rogersa15e67d2012-02-28 13:51:55 -08001082 size_t component_size = a->GetClass()->GetComponentSize();
1083 size_t byte_count = a->GetLength() * component_size;
Ian Rogersef7d42f2014-01-06 12:55:46 -08001084 void* result = GuardedCopy::Create(a->GetRawData(component_size, 0), byte_count, true);
1085 if (isCopy != nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -07001086 *isCopy = JNI_TRUE;
1087 }
1088 return result;
1089}
1090
1091/*
1092 * Perform the array "release" operation, which may or may not copy data
Elliott Hughes81ff3182012-03-23 20:35:56 -07001093 * back into the managed heap, and may or may not release the underlying storage.
Elliott Hughesa2501992011-08-26 19:39:54 -07001094 */
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001095static void ReleaseGuardedPACopy(JNIEnv* env, jarray java_array, void* dataBuf, int mode) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -07001096 ScopedObjectAccess soa(env);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001097 mirror::Array* a = soa.Decode<mirror::Array*>(java_array);
Elliott Hughesa2501992011-08-26 19:39:54 -07001098
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001099 GuardedCopy::Check(__FUNCTION__, dataBuf, true);
Elliott Hughesa2501992011-08-26 19:39:54 -07001100
1101 if (mode != JNI_ABORT) {
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001102 size_t len = GuardedCopy::FromData(dataBuf)->original_length;
Ian Rogersef7d42f2014-01-06 12:55:46 -08001103 memcpy(a->GetRawData(a->GetClass()->GetComponentSize(), 0), dataBuf, len);
Elliott Hughesa2501992011-08-26 19:39:54 -07001104 }
1105 if (mode != JNI_COMMIT) {
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001106 GuardedCopy::Destroy(dataBuf);
Elliott Hughesa2501992011-08-26 19:39:54 -07001107 }
1108}
1109
1110/*
1111 * ===========================================================================
1112 * JNI functions
1113 * ===========================================================================
1114 */
1115
1116class CheckJNI {
1117 public:
1118 static jint GetVersion(JNIEnv* env) {
1119 CHECK_JNI_ENTRY(kFlag_Default, "E", env);
1120 return CHECK_JNI_EXIT("I", baseEnv(env)->GetVersion(env));
1121 }
1122
1123 static jclass DefineClass(JNIEnv* env, const char* name, jobject loader, const jbyte* buf, jsize bufLen) {
1124 CHECK_JNI_ENTRY(kFlag_Default, "EuLpz", env, name, loader, buf, bufLen);
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001125 sc.CheckClassName(name);
Elliott Hughesa2501992011-08-26 19:39:54 -07001126 return CHECK_JNI_EXIT("c", baseEnv(env)->DefineClass(env, name, loader, buf, bufLen));
1127 }
1128
1129 static jclass FindClass(JNIEnv* env, const char* name) {
1130 CHECK_JNI_ENTRY(kFlag_Default, "Eu", env, name);
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001131 sc.CheckClassName(name);
Elliott Hughesa2501992011-08-26 19:39:54 -07001132 return CHECK_JNI_EXIT("c", baseEnv(env)->FindClass(env, name));
1133 }
1134
Elliott Hughese84278b2012-03-22 10:06:53 -07001135 static jclass GetSuperclass(JNIEnv* env, jclass c) {
1136 CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, c);
1137 return CHECK_JNI_EXIT("c", baseEnv(env)->GetSuperclass(env, c));
Elliott Hughesa2501992011-08-26 19:39:54 -07001138 }
1139
Elliott Hughese84278b2012-03-22 10:06:53 -07001140 static jboolean IsAssignableFrom(JNIEnv* env, jclass c1, jclass c2) {
1141 CHECK_JNI_ENTRY(kFlag_Default, "Ecc", env, c1, c2);
1142 return CHECK_JNI_EXIT("b", baseEnv(env)->IsAssignableFrom(env, c1, c2));
Elliott Hughesa2501992011-08-26 19:39:54 -07001143 }
1144
1145 static jmethodID FromReflectedMethod(JNIEnv* env, jobject method) {
1146 CHECK_JNI_ENTRY(kFlag_Default, "EL", env, method);
1147 // TODO: check that 'field' is a java.lang.reflect.Method.
1148 return CHECK_JNI_EXIT("m", baseEnv(env)->FromReflectedMethod(env, method));
1149 }
1150
1151 static jfieldID FromReflectedField(JNIEnv* env, jobject field) {
1152 CHECK_JNI_ENTRY(kFlag_Default, "EL", env, field);
1153 // TODO: check that 'field' is a java.lang.reflect.Field.
1154 return CHECK_JNI_EXIT("f", baseEnv(env)->FromReflectedField(env, field));
1155 }
1156
1157 static jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID mid, jboolean isStatic) {
1158 CHECK_JNI_ENTRY(kFlag_Default, "Ecmb", env, cls, mid, isStatic);
1159 return CHECK_JNI_EXIT("L", baseEnv(env)->ToReflectedMethod(env, cls, mid, isStatic));
1160 }
1161
1162 static jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fid, jboolean isStatic) {
1163 CHECK_JNI_ENTRY(kFlag_Default, "Ecfb", env, cls, fid, isStatic);
1164 return CHECK_JNI_EXIT("L", baseEnv(env)->ToReflectedField(env, cls, fid, isStatic));
1165 }
1166
1167 static jint Throw(JNIEnv* env, jthrowable obj) {
1168 CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
1169 // TODO: check that 'obj' is a java.lang.Throwable.
1170 return CHECK_JNI_EXIT("I", baseEnv(env)->Throw(env, obj));
1171 }
1172
Elliott Hughese84278b2012-03-22 10:06:53 -07001173 static jint ThrowNew(JNIEnv* env, jclass c, const char* message) {
1174 CHECK_JNI_ENTRY(kFlag_NullableUtf, "Ecu", env, c, message);
1175 return CHECK_JNI_EXIT("I", baseEnv(env)->ThrowNew(env, c, message));
Elliott Hughesa2501992011-08-26 19:39:54 -07001176 }
1177
1178 static jthrowable ExceptionOccurred(JNIEnv* env) {
1179 CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
1180 return CHECK_JNI_EXIT("L", baseEnv(env)->ExceptionOccurred(env));
1181 }
1182
1183 static void ExceptionDescribe(JNIEnv* env) {
1184 CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
1185 baseEnv(env)->ExceptionDescribe(env);
1186 CHECK_JNI_EXIT_VOID();
1187 }
1188
1189 static void ExceptionClear(JNIEnv* env) {
1190 CHECK_JNI_ENTRY(kFlag_ExcepOkay, "E", env);
1191 baseEnv(env)->ExceptionClear(env);
1192 CHECK_JNI_EXIT_VOID();
1193 }
1194
1195 static void FatalError(JNIEnv* env, const char* msg) {
Elliott Hughesc4378df2013-06-14 17:05:13 -07001196 // The JNI specification doesn't say it's okay to call FatalError with a pending exception,
1197 // but you're about to abort anyway, and it's quite likely that you have a pending exception,
1198 // and it's not unimaginable that you don't know that you do. So we allow it.
1199 CHECK_JNI_ENTRY(kFlag_ExcepOkay | kFlag_NullableUtf, "Eu", env, msg);
Elliott Hughesa2501992011-08-26 19:39:54 -07001200 baseEnv(env)->FatalError(env, msg);
1201 CHECK_JNI_EXIT_VOID();
1202 }
1203
1204 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
1205 CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EI", env, capacity);
1206 return CHECK_JNI_EXIT("I", baseEnv(env)->PushLocalFrame(env, capacity));
1207 }
1208
1209 static jobject PopLocalFrame(JNIEnv* env, jobject res) {
1210 CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, res);
1211 return CHECK_JNI_EXIT("L", baseEnv(env)->PopLocalFrame(env, res));
1212 }
1213
1214 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
1215 CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
1216 return CHECK_JNI_EXIT("L", baseEnv(env)->NewGlobalRef(env, obj));
1217 }
1218
1219 static jobject NewLocalRef(JNIEnv* env, jobject ref) {
1220 CHECK_JNI_ENTRY(kFlag_Default, "EL", env, ref);
1221 return CHECK_JNI_EXIT("L", baseEnv(env)->NewLocalRef(env, ref));
1222 }
1223
1224 static void DeleteGlobalRef(JNIEnv* env, jobject globalRef) {
1225 CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, globalRef);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001226 if (globalRef != nullptr && GetIndirectRefKind(globalRef) != kGlobal) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001227 JniAbortF(__FUNCTION__, "DeleteGlobalRef on %s: %p",
1228 ToStr<IndirectRefKind>(GetIndirectRefKind(globalRef)).c_str(), globalRef);
Elliott Hughesa2501992011-08-26 19:39:54 -07001229 } else {
1230 baseEnv(env)->DeleteGlobalRef(env, globalRef);
1231 CHECK_JNI_EXIT_VOID();
1232 }
1233 }
1234
1235 static void DeleteWeakGlobalRef(JNIEnv* env, jweak weakGlobalRef) {
1236 CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, weakGlobalRef);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001237 if (weakGlobalRef != nullptr && GetIndirectRefKind(weakGlobalRef) != kWeakGlobal) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001238 JniAbortF(__FUNCTION__, "DeleteWeakGlobalRef on %s: %p",
1239 ToStr<IndirectRefKind>(GetIndirectRefKind(weakGlobalRef)).c_str(), weakGlobalRef);
Elliott Hughesa2501992011-08-26 19:39:54 -07001240 } else {
1241 baseEnv(env)->DeleteWeakGlobalRef(env, weakGlobalRef);
1242 CHECK_JNI_EXIT_VOID();
1243 }
1244 }
1245
1246 static void DeleteLocalRef(JNIEnv* env, jobject localRef) {
1247 CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, localRef);
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001248 if (localRef != nullptr && GetIndirectRefKind(localRef) != kLocal && !IsHandleScopeLocalRef(env, localRef)) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001249 JniAbortF(__FUNCTION__, "DeleteLocalRef on %s: %p",
1250 ToStr<IndirectRefKind>(GetIndirectRefKind(localRef)).c_str(), localRef);
Elliott Hughesa2501992011-08-26 19:39:54 -07001251 } else {
1252 baseEnv(env)->DeleteLocalRef(env, localRef);
1253 CHECK_JNI_EXIT_VOID();
1254 }
1255 }
1256
1257 static jint EnsureLocalCapacity(JNIEnv *env, jint capacity) {
1258 CHECK_JNI_ENTRY(kFlag_Default, "EI", env, capacity);
1259 return CHECK_JNI_EXIT("I", baseEnv(env)->EnsureLocalCapacity(env, capacity));
1260 }
1261
1262 static jboolean IsSameObject(JNIEnv* env, jobject ref1, jobject ref2) {
1263 CHECK_JNI_ENTRY(kFlag_Default, "ELL", env, ref1, ref2);
1264 return CHECK_JNI_EXIT("b", baseEnv(env)->IsSameObject(env, ref1, ref2));
1265 }
1266
Elliott Hughese84278b2012-03-22 10:06:53 -07001267 static jobject AllocObject(JNIEnv* env, jclass c) {
1268 CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, c);
1269 return CHECK_JNI_EXIT("L", baseEnv(env)->AllocObject(env, c));
Elliott Hughesa2501992011-08-26 19:39:54 -07001270 }
1271
Elliott Hughese84278b2012-03-22 10:06:53 -07001272 static jobject NewObject(JNIEnv* env, jclass c, jmethodID mid, ...) {
1273 CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid);
Elliott Hughesa2501992011-08-26 19:39:54 -07001274 va_list args;
1275 va_start(args, mid);
Elliott Hughese84278b2012-03-22 10:06:53 -07001276 jobject result = baseEnv(env)->NewObjectV(env, c, mid, args);
Elliott Hughesa2501992011-08-26 19:39:54 -07001277 va_end(args);
1278 return CHECK_JNI_EXIT("L", result);
1279 }
1280
Elliott Hughese84278b2012-03-22 10:06:53 -07001281 static jobject NewObjectV(JNIEnv* env, jclass c, jmethodID mid, va_list args) {
1282 CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid);
1283 return CHECK_JNI_EXIT("L", baseEnv(env)->NewObjectV(env, c, mid, args));
Elliott Hughesa2501992011-08-26 19:39:54 -07001284 }
1285
Elliott Hughese84278b2012-03-22 10:06:53 -07001286 static jobject NewObjectA(JNIEnv* env, jclass c, jmethodID mid, jvalue* args) {
1287 CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid);
1288 return CHECK_JNI_EXIT("L", baseEnv(env)->NewObjectA(env, c, mid, args));
Elliott Hughesa2501992011-08-26 19:39:54 -07001289 }
1290
1291 static jclass GetObjectClass(JNIEnv* env, jobject obj) {
1292 CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
1293 return CHECK_JNI_EXIT("c", baseEnv(env)->GetObjectClass(env, obj));
1294 }
1295
Elliott Hughese84278b2012-03-22 10:06:53 -07001296 static jboolean IsInstanceOf(JNIEnv* env, jobject obj, jclass c) {
1297 CHECK_JNI_ENTRY(kFlag_Default, "ELc", env, obj, c);
1298 return CHECK_JNI_EXIT("b", baseEnv(env)->IsInstanceOf(env, obj, c));
Elliott Hughesa2501992011-08-26 19:39:54 -07001299 }
1300
Elliott Hughese84278b2012-03-22 10:06:53 -07001301 static jmethodID GetMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) {
1302 CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
1303 return CHECK_JNI_EXIT("m", baseEnv(env)->GetMethodID(env, c, name, sig));
Elliott Hughesa2501992011-08-26 19:39:54 -07001304 }
1305
Elliott Hughese84278b2012-03-22 10:06:53 -07001306 static jfieldID GetFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) {
1307 CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
1308 return CHECK_JNI_EXIT("f", baseEnv(env)->GetFieldID(env, c, name, sig));
Elliott Hughesa2501992011-08-26 19:39:54 -07001309 }
1310
Elliott Hughese84278b2012-03-22 10:06:53 -07001311 static jmethodID GetStaticMethodID(JNIEnv* env, jclass c, const char* name, const char* sig) {
1312 CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
1313 return CHECK_JNI_EXIT("m", baseEnv(env)->GetStaticMethodID(env, c, name, sig));
Elliott Hughesa2501992011-08-26 19:39:54 -07001314 }
1315
Elliott Hughese84278b2012-03-22 10:06:53 -07001316 static jfieldID GetStaticFieldID(JNIEnv* env, jclass c, const char* name, const char* sig) {
1317 CHECK_JNI_ENTRY(kFlag_Default, "Ecuu", env, c, name, sig);
1318 return CHECK_JNI_EXIT("f", baseEnv(env)->GetStaticFieldID(env, c, name, sig));
Elliott Hughesa2501992011-08-26 19:39:54 -07001319 }
1320
Ian Rogersef7d42f2014-01-06 12:55:46 -08001321#define FIELD_ACCESSORS(_ctype, _jname, _jvalue_type, _type) \
Elliott Hughese84278b2012-03-22 10:06:53 -07001322 static _ctype GetStatic##_jname##Field(JNIEnv* env, jclass c, jfieldID fid) { \
1323 CHECK_JNI_ENTRY(kFlag_Default, "Ecf", env, c, fid); \
1324 sc.CheckStaticFieldID(c, fid); \
1325 return CHECK_JNI_EXIT(_type, baseEnv(env)->GetStatic##_jname##Field(env, c, fid)); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001326 } \
1327 static _ctype Get##_jname##Field(JNIEnv* env, jobject obj, jfieldID fid) { \
1328 CHECK_JNI_ENTRY(kFlag_Default, "ELf", env, obj, fid); \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001329 sc.CheckInstanceFieldID(obj, fid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001330 return CHECK_JNI_EXIT(_type, baseEnv(env)->Get##_jname##Field(env, obj, fid)); \
1331 } \
Elliott Hughese84278b2012-03-22 10:06:53 -07001332 static void SetStatic##_jname##Field(JNIEnv* env, jclass c, jfieldID fid, _ctype value) { \
1333 CHECK_JNI_ENTRY(kFlag_Default, "Ecf" _type, env, c, fid, value); \
1334 sc.CheckStaticFieldID(c, fid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001335 /* "value" arg only used when type == ref */ \
Ian Rogersef7d42f2014-01-06 12:55:46 -08001336 jvalue java_type_value; \
1337 java_type_value._jvalue_type = value; \
1338 sc.CheckFieldType(java_type_value, fid, _type[0], true); \
Elliott Hughese84278b2012-03-22 10:06:53 -07001339 baseEnv(env)->SetStatic##_jname##Field(env, c, fid, value); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001340 CHECK_JNI_EXIT_VOID(); \
1341 } \
1342 static void Set##_jname##Field(JNIEnv* env, jobject obj, jfieldID fid, _ctype value) { \
1343 CHECK_JNI_ENTRY(kFlag_Default, "ELf" _type, env, obj, fid, value); \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001344 sc.CheckInstanceFieldID(obj, fid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001345 /* "value" arg only used when type == ref */ \
Ian Rogersef7d42f2014-01-06 12:55:46 -08001346 jvalue java_type_value; \
1347 java_type_value._jvalue_type = value; \
1348 sc.CheckFieldType(java_type_value, fid, _type[0], false); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001349 baseEnv(env)->Set##_jname##Field(env, obj, fid, value); \
1350 CHECK_JNI_EXIT_VOID(); \
1351 }
1352
Ian Rogersef7d42f2014-01-06 12:55:46 -08001353FIELD_ACCESSORS(jobject, Object, l, "L");
1354FIELD_ACCESSORS(jboolean, Boolean, z, "Z");
1355FIELD_ACCESSORS(jbyte, Byte, b, "B");
1356FIELD_ACCESSORS(jchar, Char, c, "C");
1357FIELD_ACCESSORS(jshort, Short, s, "S");
1358FIELD_ACCESSORS(jint, Int, i, "I");
1359FIELD_ACCESSORS(jlong, Long, j, "J");
1360FIELD_ACCESSORS(jfloat, Float, f, "F");
1361FIELD_ACCESSORS(jdouble, Double, d, "D");
Elliott Hughesa2501992011-08-26 19:39:54 -07001362
1363#define CALL(_ctype, _jname, _retdecl, _retasgn, _retok, _retsig) \
1364 /* Virtual... */ \
1365 static _ctype Call##_jname##Method(JNIEnv* env, jobject obj, \
1366 jmethodID mid, ...) \
1367 { \
1368 CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001369 sc.CheckSig(mid, _retsig, false); \
1370 sc.CheckVirtualMethod(obj, mid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001371 _retdecl; \
1372 va_list args; \
1373 va_start(args, mid); \
Elliott Hughesba8eee12012-01-24 20:25:24 -08001374 _retasgn(baseEnv(env)->Call##_jname##MethodV(env, obj, mid, args)); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001375 va_end(args); \
1376 _retok; \
1377 } \
1378 static _ctype Call##_jname##MethodV(JNIEnv* env, jobject obj, \
1379 jmethodID mid, va_list args) \
1380 { \
1381 CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001382 sc.CheckSig(mid, _retsig, false); \
1383 sc.CheckVirtualMethod(obj, mid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001384 _retdecl; \
Elliott Hughesba8eee12012-01-24 20:25:24 -08001385 _retasgn(baseEnv(env)->Call##_jname##MethodV(env, obj, mid, args)); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001386 _retok; \
1387 } \
1388 static _ctype Call##_jname##MethodA(JNIEnv* env, jobject obj, \
1389 jmethodID mid, jvalue* args) \
1390 { \
1391 CHECK_JNI_ENTRY(kFlag_Default, "ELm.", env, obj, mid); /* TODO: args! */ \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001392 sc.CheckSig(mid, _retsig, false); \
1393 sc.CheckVirtualMethod(obj, mid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001394 _retdecl; \
Elliott Hughesba8eee12012-01-24 20:25:24 -08001395 _retasgn(baseEnv(env)->Call##_jname##MethodA(env, obj, mid, args)); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001396 _retok; \
1397 } \
1398 /* Non-virtual... */ \
1399 static _ctype CallNonvirtual##_jname##Method(JNIEnv* env, \
Elliott Hughese84278b2012-03-22 10:06:53 -07001400 jobject obj, jclass c, jmethodID mid, ...) \
Elliott Hughesa2501992011-08-26 19:39:54 -07001401 { \
Elliott Hughese84278b2012-03-22 10:06:53 -07001402 CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, c, mid); /* TODO: args! */ \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001403 sc.CheckSig(mid, _retsig, false); \
1404 sc.CheckVirtualMethod(obj, mid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001405 _retdecl; \
1406 va_list args; \
1407 va_start(args, mid); \
Elliott Hughese84278b2012-03-22 10:06:53 -07001408 _retasgn(baseEnv(env)->CallNonvirtual##_jname##MethodV(env, obj, c, mid, args)); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001409 va_end(args); \
1410 _retok; \
1411 } \
1412 static _ctype CallNonvirtual##_jname##MethodV(JNIEnv* env, \
Elliott Hughese84278b2012-03-22 10:06:53 -07001413 jobject obj, jclass c, jmethodID mid, va_list args) \
Elliott Hughesa2501992011-08-26 19:39:54 -07001414 { \
Elliott Hughese84278b2012-03-22 10:06:53 -07001415 CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, c, mid); /* TODO: args! */ \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001416 sc.CheckSig(mid, _retsig, false); \
1417 sc.CheckVirtualMethod(obj, mid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001418 _retdecl; \
Elliott Hughese84278b2012-03-22 10:06:53 -07001419 _retasgn(baseEnv(env)->CallNonvirtual##_jname##MethodV(env, obj, c, mid, args)); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001420 _retok; \
1421 } \
1422 static _ctype CallNonvirtual##_jname##MethodA(JNIEnv* env, \
Elliott Hughese84278b2012-03-22 10:06:53 -07001423 jobject obj, jclass c, jmethodID mid, jvalue* args) \
Elliott Hughesa2501992011-08-26 19:39:54 -07001424 { \
Elliott Hughese84278b2012-03-22 10:06:53 -07001425 CHECK_JNI_ENTRY(kFlag_Default, "ELcm.", env, obj, c, mid); /* TODO: args! */ \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001426 sc.CheckSig(mid, _retsig, false); \
1427 sc.CheckVirtualMethod(obj, mid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001428 _retdecl; \
Elliott Hughese84278b2012-03-22 10:06:53 -07001429 _retasgn(baseEnv(env)->CallNonvirtual##_jname##MethodA(env, obj, c, mid, args)); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001430 _retok; \
1431 } \
1432 /* Static... */ \
Elliott Hughese84278b2012-03-22 10:06:53 -07001433 static _ctype CallStatic##_jname##Method(JNIEnv* env, jclass c, jmethodID mid, ...) \
Elliott Hughesa2501992011-08-26 19:39:54 -07001434 { \
Elliott Hughese84278b2012-03-22 10:06:53 -07001435 CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid); /* TODO: args! */ \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001436 sc.CheckSig(mid, _retsig, true); \
Elliott Hughese84278b2012-03-22 10:06:53 -07001437 sc.CheckStaticMethod(c, mid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001438 _retdecl; \
1439 va_list args; \
1440 va_start(args, mid); \
Elliott Hughese84278b2012-03-22 10:06:53 -07001441 _retasgn(baseEnv(env)->CallStatic##_jname##MethodV(env, c, mid, args)); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001442 va_end(args); \
1443 _retok; \
1444 } \
Elliott Hughese84278b2012-03-22 10:06:53 -07001445 static _ctype CallStatic##_jname##MethodV(JNIEnv* env, jclass c, jmethodID mid, va_list args) \
Elliott Hughesa2501992011-08-26 19:39:54 -07001446 { \
Elliott Hughese84278b2012-03-22 10:06:53 -07001447 CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid); /* TODO: args! */ \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001448 sc.CheckSig(mid, _retsig, true); \
Elliott Hughese84278b2012-03-22 10:06:53 -07001449 sc.CheckStaticMethod(c, mid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001450 _retdecl; \
Elliott Hughese84278b2012-03-22 10:06:53 -07001451 _retasgn(baseEnv(env)->CallStatic##_jname##MethodV(env, c, mid, args)); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001452 _retok; \
1453 } \
Elliott Hughese84278b2012-03-22 10:06:53 -07001454 static _ctype CallStatic##_jname##MethodA(JNIEnv* env, jclass c, jmethodID mid, jvalue* args) \
Elliott Hughesa2501992011-08-26 19:39:54 -07001455 { \
Elliott Hughese84278b2012-03-22 10:06:53 -07001456 CHECK_JNI_ENTRY(kFlag_Default, "Ecm.", env, c, mid); /* TODO: args! */ \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001457 sc.CheckSig(mid, _retsig, true); \
Elliott Hughese84278b2012-03-22 10:06:53 -07001458 sc.CheckStaticMethod(c, mid); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001459 _retdecl; \
Elliott Hughese84278b2012-03-22 10:06:53 -07001460 _retasgn(baseEnv(env)->CallStatic##_jname##MethodA(env, c, mid, args)); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001461 _retok; \
1462 }
1463
1464#define NON_VOID_RETURN(_retsig, _ctype) return CHECK_JNI_EXIT(_retsig, (_ctype) result)
1465#define VOID_RETURN CHECK_JNI_EXIT_VOID()
1466
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001467CALL(jobject, Object, mirror::Object* result, result = reinterpret_cast<mirror::Object*>, NON_VOID_RETURN("L", jobject), "L");
Elliott Hughesba8eee12012-01-24 20:25:24 -08001468CALL(jboolean, Boolean, jboolean result, result =, NON_VOID_RETURN("Z", jboolean), "Z");
1469CALL(jbyte, Byte, jbyte result, result =, NON_VOID_RETURN("B", jbyte), "B");
1470CALL(jchar, Char, jchar result, result =, NON_VOID_RETURN("C", jchar), "C");
1471CALL(jshort, Short, jshort result, result =, NON_VOID_RETURN("S", jshort), "S");
1472CALL(jint, Int, jint result, result =, NON_VOID_RETURN("I", jint), "I");
1473CALL(jlong, Long, jlong result, result =, NON_VOID_RETURN("J", jlong), "J");
1474CALL(jfloat, Float, jfloat result, result =, NON_VOID_RETURN("F", jfloat), "F");
1475CALL(jdouble, Double, jdouble result, result =, NON_VOID_RETURN("D", jdouble), "D");
Elliott Hughesa2501992011-08-26 19:39:54 -07001476CALL(void, Void, , , VOID_RETURN, "V");
1477
1478 static jstring NewString(JNIEnv* env, const jchar* unicodeChars, jsize len) {
1479 CHECK_JNI_ENTRY(kFlag_Default, "Epz", env, unicodeChars, len);
1480 return CHECK_JNI_EXIT("s", baseEnv(env)->NewString(env, unicodeChars, len));
1481 }
1482
1483 static jsize GetStringLength(JNIEnv* env, jstring string) {
1484 CHECK_JNI_ENTRY(kFlag_CritOkay, "Es", env, string);
1485 return CHECK_JNI_EXIT("I", baseEnv(env)->GetStringLength(env, string));
1486 }
1487
1488 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* isCopy) {
1489 CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, java_string, isCopy);
1490 const jchar* result = baseEnv(env)->GetStringChars(env, java_string, isCopy);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001491 if (sc.ForceCopy() && result != nullptr) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001492 mirror::String* s = sc.soa().Decode<mirror::String*>(java_string);
Elliott Hughesa2501992011-08-26 19:39:54 -07001493 int byteCount = s->GetLength() * 2;
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001494 result = (const jchar*) GuardedCopy::Create(result, byteCount, false);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001495 if (isCopy != nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -07001496 *isCopy = JNI_TRUE;
1497 }
1498 }
1499 return CHECK_JNI_EXIT("p", result);
1500 }
1501
1502 static void ReleaseStringChars(JNIEnv* env, jstring string, const jchar* chars) {
1503 CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "Esp", env, string, chars);
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001504 sc.CheckNonNull(chars);
1505 if (sc.ForceCopy()) {
1506 GuardedCopy::Check(__FUNCTION__, chars, false);
Elliott Hughesba8eee12012-01-24 20:25:24 -08001507 chars = reinterpret_cast<const jchar*>(GuardedCopy::Destroy(const_cast<jchar*>(chars)));
Elliott Hughesa2501992011-08-26 19:39:54 -07001508 }
1509 baseEnv(env)->ReleaseStringChars(env, string, chars);
1510 CHECK_JNI_EXIT_VOID();
1511 }
1512
1513 static jstring NewStringUTF(JNIEnv* env, const char* bytes) {
Brian Carlstrom7934ac22013-07-26 10:54:15 -07001514 CHECK_JNI_ENTRY(kFlag_NullableUtf, "Eu", env, bytes); // TODO: show pointer and truncate string.
Elliott Hughesa2501992011-08-26 19:39:54 -07001515 return CHECK_JNI_EXIT("s", baseEnv(env)->NewStringUTF(env, bytes));
1516 }
1517
1518 static jsize GetStringUTFLength(JNIEnv* env, jstring string) {
1519 CHECK_JNI_ENTRY(kFlag_CritOkay, "Es", env, string);
1520 return CHECK_JNI_EXIT("I", baseEnv(env)->GetStringUTFLength(env, string));
1521 }
1522
1523 static const char* GetStringUTFChars(JNIEnv* env, jstring string, jboolean* isCopy) {
1524 CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, string, isCopy);
1525 const char* result = baseEnv(env)->GetStringUTFChars(env, string, isCopy);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001526 if (sc.ForceCopy() && result != nullptr) {
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001527 result = (const char*) GuardedCopy::Create(result, strlen(result) + 1, false);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001528 if (isCopy != nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -07001529 *isCopy = JNI_TRUE;
1530 }
1531 }
Brian Carlstrom7934ac22013-07-26 10:54:15 -07001532 return CHECK_JNI_EXIT("u", result); // TODO: show pointer and truncate string.
Elliott Hughesa2501992011-08-26 19:39:54 -07001533 }
1534
1535 static void ReleaseStringUTFChars(JNIEnv* env, jstring string, const char* utf) {
Brian Carlstrom7934ac22013-07-26 10:54:15 -07001536 CHECK_JNI_ENTRY(kFlag_ExcepOkay | kFlag_Release, "Esu", env, string, utf); // TODO: show pointer and truncate string.
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001537 if (sc.ForceCopy()) {
1538 GuardedCopy::Check(__FUNCTION__, utf, false);
Elliott Hughesba8eee12012-01-24 20:25:24 -08001539 utf = reinterpret_cast<const char*>(GuardedCopy::Destroy(const_cast<char*>(utf)));
Elliott Hughesa2501992011-08-26 19:39:54 -07001540 }
1541 baseEnv(env)->ReleaseStringUTFChars(env, string, utf);
1542 CHECK_JNI_EXIT_VOID();
1543 }
1544
1545 static jsize GetArrayLength(JNIEnv* env, jarray array) {
1546 CHECK_JNI_ENTRY(kFlag_CritOkay, "Ea", env, array);
1547 return CHECK_JNI_EXIT("I", baseEnv(env)->GetArrayLength(env, array));
1548 }
1549
1550 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass elementClass, jobject initialElement) {
1551 CHECK_JNI_ENTRY(kFlag_Default, "EzcL", env, length, elementClass, initialElement);
1552 return CHECK_JNI_EXIT("a", baseEnv(env)->NewObjectArray(env, length, elementClass, initialElement));
1553 }
1554
1555 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index) {
1556 CHECK_JNI_ENTRY(kFlag_Default, "EaI", env, array, index);
1557 return CHECK_JNI_EXIT("L", baseEnv(env)->GetObjectArrayElement(env, array, index));
1558 }
1559
1560 static void SetObjectArrayElement(JNIEnv* env, jobjectArray array, jsize index, jobject value) {
1561 CHECK_JNI_ENTRY(kFlag_Default, "EaIL", env, array, index, value);
1562 baseEnv(env)->SetObjectArrayElement(env, array, index, value);
1563 CHECK_JNI_EXIT_VOID();
1564 }
1565
1566#define NEW_PRIMITIVE_ARRAY(_artype, _jname) \
1567 static _artype New##_jname##Array(JNIEnv* env, jsize length) { \
1568 CHECK_JNI_ENTRY(kFlag_Default, "Ez", env, length); \
1569 return CHECK_JNI_EXIT("a", baseEnv(env)->New##_jname##Array(env, length)); \
1570 }
1571NEW_PRIMITIVE_ARRAY(jbooleanArray, Boolean);
1572NEW_PRIMITIVE_ARRAY(jbyteArray, Byte);
1573NEW_PRIMITIVE_ARRAY(jcharArray, Char);
1574NEW_PRIMITIVE_ARRAY(jshortArray, Short);
1575NEW_PRIMITIVE_ARRAY(jintArray, Int);
1576NEW_PRIMITIVE_ARRAY(jlongArray, Long);
1577NEW_PRIMITIVE_ARRAY(jfloatArray, Float);
1578NEW_PRIMITIVE_ARRAY(jdoubleArray, Double);
1579
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001580struct ForceCopyGetChecker {
Elliott Hughesba8eee12012-01-24 20:25:24 -08001581 public:
Elliott Hughesa2501992011-08-26 19:39:54 -07001582 ForceCopyGetChecker(ScopedCheck& sc, jboolean* isCopy) {
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001583 force_copy = sc.ForceCopy();
1584 no_copy = 0;
Ian Rogersef7d42f2014-01-06 12:55:46 -08001585 if (force_copy && isCopy != nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001586 // Capture this before the base call tramples on it.
Elliott Hughesba8eee12012-01-24 20:25:24 -08001587 no_copy = *reinterpret_cast<uint32_t*>(isCopy);
Elliott Hughesa2501992011-08-26 19:39:54 -07001588 }
1589 }
1590
1591 template<typename ResultT>
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001592 ResultT Check(JNIEnv* env, jarray array, jboolean* isCopy, ResultT result) {
Ian Rogersef7d42f2014-01-06 12:55:46 -08001593 if (force_copy && result != nullptr) {
Mathieu Chartier77129ff2013-10-18 11:36:46 -07001594 result = reinterpret_cast<ResultT>(CreateGuardedPACopy(env, array, isCopy));
Elliott Hughesa2501992011-08-26 19:39:54 -07001595 }
1596 return result;
1597 }
1598
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001599 uint32_t no_copy;
1600 bool force_copy;
Elliott Hughesa2501992011-08-26 19:39:54 -07001601};
1602
1603#define GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname) \
1604 static _ctype* Get##_jname##ArrayElements(JNIEnv* env, _ctype##Array array, jboolean* isCopy) { \
1605 CHECK_JNI_ENTRY(kFlag_Default, "Eap", env, array, isCopy); \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001606 _ctype* result = ForceCopyGetChecker(sc, isCopy).Check(env, array, isCopy, baseEnv(env)->Get##_jname##ArrayElements(env, array, isCopy)); \
Elliott Hughesa2501992011-08-26 19:39:54 -07001607 return CHECK_JNI_EXIT("p", result); \
1608 }
1609
1610#define RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname) \
1611 static void Release##_jname##ArrayElements(JNIEnv* env, _ctype##Array array, _ctype* elems, jint mode) { \
1612 CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "Eapr", env, array, elems, mode); \
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001613 sc.CheckNonNull(elems); \
1614 if (sc.ForceCopy()) { \
Elliott Hughesa2501992011-08-26 19:39:54 -07001615 ReleaseGuardedPACopy(env, array, elems, mode); \
1616 } \
1617 baseEnv(env)->Release##_jname##ArrayElements(env, array, elems, mode); \
1618 CHECK_JNI_EXIT_VOID(); \
1619 }
1620
1621#define GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname) \
1622 static void Get##_jname##ArrayRegion(JNIEnv* env, _ctype##Array array, jsize start, jsize len, _ctype* buf) { \
1623 CHECK_JNI_ENTRY(kFlag_Default, "EaIIp", env, array, start, len, buf); \
1624 baseEnv(env)->Get##_jname##ArrayRegion(env, array, start, len, buf); \
1625 CHECK_JNI_EXIT_VOID(); \
1626 }
1627
1628#define SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname) \
1629 static void Set##_jname##ArrayRegion(JNIEnv* env, _ctype##Array array, jsize start, jsize len, const _ctype* buf) { \
1630 CHECK_JNI_ENTRY(kFlag_Default, "EaIIp", env, array, start, len, buf); \
1631 baseEnv(env)->Set##_jname##ArrayRegion(env, array, start, len, buf); \
1632 CHECK_JNI_EXIT_VOID(); \
1633 }
1634
1635#define PRIMITIVE_ARRAY_FUNCTIONS(_ctype, _jname, _typechar) \
1636 GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname); \
1637 RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname); \
1638 GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname); \
1639 SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname);
1640
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001641// TODO: verify primitive array type matches call type.
Elliott Hughesa2501992011-08-26 19:39:54 -07001642PRIMITIVE_ARRAY_FUNCTIONS(jboolean, Boolean, 'Z');
1643PRIMITIVE_ARRAY_FUNCTIONS(jbyte, Byte, 'B');
1644PRIMITIVE_ARRAY_FUNCTIONS(jchar, Char, 'C');
1645PRIMITIVE_ARRAY_FUNCTIONS(jshort, Short, 'S');
1646PRIMITIVE_ARRAY_FUNCTIONS(jint, Int, 'I');
1647PRIMITIVE_ARRAY_FUNCTIONS(jlong, Long, 'J');
1648PRIMITIVE_ARRAY_FUNCTIONS(jfloat, Float, 'F');
1649PRIMITIVE_ARRAY_FUNCTIONS(jdouble, Double, 'D');
1650
Elliott Hughese84278b2012-03-22 10:06:53 -07001651 static jint RegisterNatives(JNIEnv* env, jclass c, const JNINativeMethod* methods, jint nMethods) {
1652 CHECK_JNI_ENTRY(kFlag_Default, "EcpI", env, c, methods, nMethods);
1653 return CHECK_JNI_EXIT("I", baseEnv(env)->RegisterNatives(env, c, methods, nMethods));
Elliott Hughesa2501992011-08-26 19:39:54 -07001654 }
1655
Elliott Hughese84278b2012-03-22 10:06:53 -07001656 static jint UnregisterNatives(JNIEnv* env, jclass c) {
1657 CHECK_JNI_ENTRY(kFlag_Default, "Ec", env, c);
1658 return CHECK_JNI_EXIT("I", baseEnv(env)->UnregisterNatives(env, c));
Elliott Hughesa2501992011-08-26 19:39:54 -07001659 }
1660
1661 static jint MonitorEnter(JNIEnv* env, jobject obj) {
1662 CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
Elliott Hughesa92853e2012-02-07 16:09:27 -08001663 if (!sc.CheckInstance(ScopedCheck::kObject, obj)) {
Brian Carlstrom7934ac22013-07-26 10:54:15 -07001664 return JNI_ERR; // Only for jni_internal_test. Real code will have aborted already.
Elliott Hughesa92853e2012-02-07 16:09:27 -08001665 }
Elliott Hughesa2501992011-08-26 19:39:54 -07001666 return CHECK_JNI_EXIT("I", baseEnv(env)->MonitorEnter(env, obj));
1667 }
1668
1669 static jint MonitorExit(JNIEnv* env, jobject obj) {
1670 CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, obj);
Elliott Hughesa92853e2012-02-07 16:09:27 -08001671 if (!sc.CheckInstance(ScopedCheck::kObject, obj)) {
Brian Carlstrom7934ac22013-07-26 10:54:15 -07001672 return JNI_ERR; // Only for jni_internal_test. Real code will have aborted already.
Elliott Hughesa92853e2012-02-07 16:09:27 -08001673 }
Elliott Hughesa2501992011-08-26 19:39:54 -07001674 return CHECK_JNI_EXIT("I", baseEnv(env)->MonitorExit(env, obj));
1675 }
1676
1677 static jint GetJavaVM(JNIEnv *env, JavaVM **vm) {
1678 CHECK_JNI_ENTRY(kFlag_Default, "Ep", env, vm);
1679 return CHECK_JNI_EXIT("I", baseEnv(env)->GetJavaVM(env, vm));
1680 }
1681
1682 static void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar* buf) {
1683 CHECK_JNI_ENTRY(kFlag_CritOkay, "EsIIp", env, str, start, len, buf);
1684 baseEnv(env)->GetStringRegion(env, str, start, len, buf);
1685 CHECK_JNI_EXIT_VOID();
1686 }
1687
1688 static void GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len, char* buf) {
1689 CHECK_JNI_ENTRY(kFlag_CritOkay, "EsIIp", env, str, start, len, buf);
1690 baseEnv(env)->GetStringUTFRegion(env, str, start, len, buf);
1691 CHECK_JNI_EXIT_VOID();
1692 }
1693
1694 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray array, jboolean* isCopy) {
1695 CHECK_JNI_ENTRY(kFlag_CritGet, "Eap", env, array, isCopy);
1696 void* result = baseEnv(env)->GetPrimitiveArrayCritical(env, array, isCopy);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001697 if (sc.ForceCopy() && result != nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -07001698 result = CreateGuardedPACopy(env, array, isCopy);
1699 }
1700 return CHECK_JNI_EXIT("p", result);
1701 }
1702
1703 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void* carray, jint mode) {
1704 CHECK_JNI_ENTRY(kFlag_CritRelease | kFlag_ExcepOkay, "Eapr", env, array, carray, mode);
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001705 sc.CheckNonNull(carray);
1706 if (sc.ForceCopy()) {
Elliott Hughesa2501992011-08-26 19:39:54 -07001707 ReleaseGuardedPACopy(env, array, carray, mode);
1708 }
1709 baseEnv(env)->ReleasePrimitiveArrayCritical(env, array, carray, mode);
1710 CHECK_JNI_EXIT_VOID();
1711 }
1712
1713 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* isCopy) {
1714 CHECK_JNI_ENTRY(kFlag_CritGet, "Esp", env, java_string, isCopy);
1715 const jchar* result = baseEnv(env)->GetStringCritical(env, java_string, isCopy);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001716 if (sc.ForceCopy() && result != nullptr) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001717 mirror::String* s = sc.soa().Decode<mirror::String*>(java_string);
Elliott Hughesa2501992011-08-26 19:39:54 -07001718 int byteCount = s->GetLength() * 2;
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001719 result = (const jchar*) GuardedCopy::Create(result, byteCount, false);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001720 if (isCopy != nullptr) {
Elliott Hughesa2501992011-08-26 19:39:54 -07001721 *isCopy = JNI_TRUE;
1722 }
1723 }
1724 return CHECK_JNI_EXIT("p", result);
1725 }
1726
1727 static void ReleaseStringCritical(JNIEnv* env, jstring string, const jchar* carray) {
1728 CHECK_JNI_ENTRY(kFlag_CritRelease | kFlag_ExcepOkay, "Esp", env, string, carray);
Elliott Hughes32ae6e32011-09-27 10:46:50 -07001729 sc.CheckNonNull(carray);
1730 if (sc.ForceCopy()) {
1731 GuardedCopy::Check(__FUNCTION__, carray, false);
Elliott Hughesba8eee12012-01-24 20:25:24 -08001732 carray = reinterpret_cast<const jchar*>(GuardedCopy::Destroy(const_cast<jchar*>(carray)));
Elliott Hughesa2501992011-08-26 19:39:54 -07001733 }
1734 baseEnv(env)->ReleaseStringCritical(env, string, carray);
1735 CHECK_JNI_EXIT_VOID();
1736 }
1737
1738 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
1739 CHECK_JNI_ENTRY(kFlag_Default, "EL", env, obj);
1740 return CHECK_JNI_EXIT("L", baseEnv(env)->NewWeakGlobalRef(env, obj));
1741 }
1742
1743 static jboolean ExceptionCheck(JNIEnv* env) {
1744 CHECK_JNI_ENTRY(kFlag_CritOkay | kFlag_ExcepOkay, "E", env);
1745 return CHECK_JNI_EXIT("b", baseEnv(env)->ExceptionCheck(env));
1746 }
1747
1748 static jobjectRefType GetObjectRefType(JNIEnv* env, jobject obj) {
1749 // Note: we use "Ep" rather than "EL" because this is the one JNI function
1750 // that it's okay to pass an invalid reference to.
1751 CHECK_JNI_ENTRY(kFlag_Default, "Ep", env, obj);
1752 // TODO: proper decoding of jobjectRefType!
1753 return CHECK_JNI_EXIT("I", baseEnv(env)->GetObjectRefType(env, obj));
1754 }
1755
1756 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
1757 CHECK_JNI_ENTRY(kFlag_Default, "EpJ", env, address, capacity);
Ian Rogersef7d42f2014-01-06 12:55:46 -08001758 if (address == nullptr) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -07001759 JniAbortF(__FUNCTION__, "non-nullable address is NULL");
Brian Carlstrom45d26c82014-06-24 23:36:28 -07001760 return nullptr;
Elliott Hughesa2501992011-08-26 19:39:54 -07001761 }
1762 return CHECK_JNI_EXIT("L", baseEnv(env)->NewDirectByteBuffer(env, address, capacity));
1763 }
1764
1765 static void* GetDirectBufferAddress(JNIEnv* env, jobject buf) {
1766 CHECK_JNI_ENTRY(kFlag_Default, "EL", env, buf);
1767 // TODO: check that 'buf' is a java.nio.Buffer.
1768 return CHECK_JNI_EXIT("p", baseEnv(env)->GetDirectBufferAddress(env, buf));
1769 }
1770
1771 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf) {
1772 CHECK_JNI_ENTRY(kFlag_Default, "EL", env, buf);
1773 // TODO: check that 'buf' is a java.nio.Buffer.
1774 return CHECK_JNI_EXIT("J", baseEnv(env)->GetDirectBufferCapacity(env, buf));
1775 }
1776
1777 private:
1778 static inline const JNINativeInterface* baseEnv(JNIEnv* env) {
1779 return reinterpret_cast<JNIEnvExt*>(env)->unchecked_functions;
1780 }
1781};
1782
1783const JNINativeInterface gCheckNativeInterface = {
Ian Rogersef7d42f2014-01-06 12:55:46 -08001784 nullptr, // reserved0.
1785 nullptr, // reserved1.
1786 nullptr, // reserved2.
1787 nullptr, // reserved3.
Elliott Hughesa2501992011-08-26 19:39:54 -07001788 CheckJNI::GetVersion,
1789 CheckJNI::DefineClass,
1790 CheckJNI::FindClass,
1791 CheckJNI::FromReflectedMethod,
1792 CheckJNI::FromReflectedField,
1793 CheckJNI::ToReflectedMethod,
1794 CheckJNI::GetSuperclass,
1795 CheckJNI::IsAssignableFrom,
1796 CheckJNI::ToReflectedField,
1797 CheckJNI::Throw,
1798 CheckJNI::ThrowNew,
1799 CheckJNI::ExceptionOccurred,
1800 CheckJNI::ExceptionDescribe,
1801 CheckJNI::ExceptionClear,
1802 CheckJNI::FatalError,
1803 CheckJNI::PushLocalFrame,
1804 CheckJNI::PopLocalFrame,
1805 CheckJNI::NewGlobalRef,
1806 CheckJNI::DeleteGlobalRef,
1807 CheckJNI::DeleteLocalRef,
1808 CheckJNI::IsSameObject,
1809 CheckJNI::NewLocalRef,
1810 CheckJNI::EnsureLocalCapacity,
1811 CheckJNI::AllocObject,
1812 CheckJNI::NewObject,
1813 CheckJNI::NewObjectV,
1814 CheckJNI::NewObjectA,
1815 CheckJNI::GetObjectClass,
1816 CheckJNI::IsInstanceOf,
1817 CheckJNI::GetMethodID,
1818 CheckJNI::CallObjectMethod,
1819 CheckJNI::CallObjectMethodV,
1820 CheckJNI::CallObjectMethodA,
1821 CheckJNI::CallBooleanMethod,
1822 CheckJNI::CallBooleanMethodV,
1823 CheckJNI::CallBooleanMethodA,
1824 CheckJNI::CallByteMethod,
1825 CheckJNI::CallByteMethodV,
1826 CheckJNI::CallByteMethodA,
1827 CheckJNI::CallCharMethod,
1828 CheckJNI::CallCharMethodV,
1829 CheckJNI::CallCharMethodA,
1830 CheckJNI::CallShortMethod,
1831 CheckJNI::CallShortMethodV,
1832 CheckJNI::CallShortMethodA,
1833 CheckJNI::CallIntMethod,
1834 CheckJNI::CallIntMethodV,
1835 CheckJNI::CallIntMethodA,
1836 CheckJNI::CallLongMethod,
1837 CheckJNI::CallLongMethodV,
1838 CheckJNI::CallLongMethodA,
1839 CheckJNI::CallFloatMethod,
1840 CheckJNI::CallFloatMethodV,
1841 CheckJNI::CallFloatMethodA,
1842 CheckJNI::CallDoubleMethod,
1843 CheckJNI::CallDoubleMethodV,
1844 CheckJNI::CallDoubleMethodA,
1845 CheckJNI::CallVoidMethod,
1846 CheckJNI::CallVoidMethodV,
1847 CheckJNI::CallVoidMethodA,
1848 CheckJNI::CallNonvirtualObjectMethod,
1849 CheckJNI::CallNonvirtualObjectMethodV,
1850 CheckJNI::CallNonvirtualObjectMethodA,
1851 CheckJNI::CallNonvirtualBooleanMethod,
1852 CheckJNI::CallNonvirtualBooleanMethodV,
1853 CheckJNI::CallNonvirtualBooleanMethodA,
1854 CheckJNI::CallNonvirtualByteMethod,
1855 CheckJNI::CallNonvirtualByteMethodV,
1856 CheckJNI::CallNonvirtualByteMethodA,
1857 CheckJNI::CallNonvirtualCharMethod,
1858 CheckJNI::CallNonvirtualCharMethodV,
1859 CheckJNI::CallNonvirtualCharMethodA,
1860 CheckJNI::CallNonvirtualShortMethod,
1861 CheckJNI::CallNonvirtualShortMethodV,
1862 CheckJNI::CallNonvirtualShortMethodA,
1863 CheckJNI::CallNonvirtualIntMethod,
1864 CheckJNI::CallNonvirtualIntMethodV,
1865 CheckJNI::CallNonvirtualIntMethodA,
1866 CheckJNI::CallNonvirtualLongMethod,
1867 CheckJNI::CallNonvirtualLongMethodV,
1868 CheckJNI::CallNonvirtualLongMethodA,
1869 CheckJNI::CallNonvirtualFloatMethod,
1870 CheckJNI::CallNonvirtualFloatMethodV,
1871 CheckJNI::CallNonvirtualFloatMethodA,
1872 CheckJNI::CallNonvirtualDoubleMethod,
1873 CheckJNI::CallNonvirtualDoubleMethodV,
1874 CheckJNI::CallNonvirtualDoubleMethodA,
1875 CheckJNI::CallNonvirtualVoidMethod,
1876 CheckJNI::CallNonvirtualVoidMethodV,
1877 CheckJNI::CallNonvirtualVoidMethodA,
1878 CheckJNI::GetFieldID,
1879 CheckJNI::GetObjectField,
1880 CheckJNI::GetBooleanField,
1881 CheckJNI::GetByteField,
1882 CheckJNI::GetCharField,
1883 CheckJNI::GetShortField,
1884 CheckJNI::GetIntField,
1885 CheckJNI::GetLongField,
1886 CheckJNI::GetFloatField,
1887 CheckJNI::GetDoubleField,
1888 CheckJNI::SetObjectField,
1889 CheckJNI::SetBooleanField,
1890 CheckJNI::SetByteField,
1891 CheckJNI::SetCharField,
1892 CheckJNI::SetShortField,
1893 CheckJNI::SetIntField,
1894 CheckJNI::SetLongField,
1895 CheckJNI::SetFloatField,
1896 CheckJNI::SetDoubleField,
1897 CheckJNI::GetStaticMethodID,
1898 CheckJNI::CallStaticObjectMethod,
1899 CheckJNI::CallStaticObjectMethodV,
1900 CheckJNI::CallStaticObjectMethodA,
1901 CheckJNI::CallStaticBooleanMethod,
1902 CheckJNI::CallStaticBooleanMethodV,
1903 CheckJNI::CallStaticBooleanMethodA,
1904 CheckJNI::CallStaticByteMethod,
1905 CheckJNI::CallStaticByteMethodV,
1906 CheckJNI::CallStaticByteMethodA,
1907 CheckJNI::CallStaticCharMethod,
1908 CheckJNI::CallStaticCharMethodV,
1909 CheckJNI::CallStaticCharMethodA,
1910 CheckJNI::CallStaticShortMethod,
1911 CheckJNI::CallStaticShortMethodV,
1912 CheckJNI::CallStaticShortMethodA,
1913 CheckJNI::CallStaticIntMethod,
1914 CheckJNI::CallStaticIntMethodV,
1915 CheckJNI::CallStaticIntMethodA,
1916 CheckJNI::CallStaticLongMethod,
1917 CheckJNI::CallStaticLongMethodV,
1918 CheckJNI::CallStaticLongMethodA,
1919 CheckJNI::CallStaticFloatMethod,
1920 CheckJNI::CallStaticFloatMethodV,
1921 CheckJNI::CallStaticFloatMethodA,
1922 CheckJNI::CallStaticDoubleMethod,
1923 CheckJNI::CallStaticDoubleMethodV,
1924 CheckJNI::CallStaticDoubleMethodA,
1925 CheckJNI::CallStaticVoidMethod,
1926 CheckJNI::CallStaticVoidMethodV,
1927 CheckJNI::CallStaticVoidMethodA,
1928 CheckJNI::GetStaticFieldID,
1929 CheckJNI::GetStaticObjectField,
1930 CheckJNI::GetStaticBooleanField,
1931 CheckJNI::GetStaticByteField,
1932 CheckJNI::GetStaticCharField,
1933 CheckJNI::GetStaticShortField,
1934 CheckJNI::GetStaticIntField,
1935 CheckJNI::GetStaticLongField,
1936 CheckJNI::GetStaticFloatField,
1937 CheckJNI::GetStaticDoubleField,
1938 CheckJNI::SetStaticObjectField,
1939 CheckJNI::SetStaticBooleanField,
1940 CheckJNI::SetStaticByteField,
1941 CheckJNI::SetStaticCharField,
1942 CheckJNI::SetStaticShortField,
1943 CheckJNI::SetStaticIntField,
1944 CheckJNI::SetStaticLongField,
1945 CheckJNI::SetStaticFloatField,
1946 CheckJNI::SetStaticDoubleField,
1947 CheckJNI::NewString,
1948 CheckJNI::GetStringLength,
1949 CheckJNI::GetStringChars,
1950 CheckJNI::ReleaseStringChars,
1951 CheckJNI::NewStringUTF,
1952 CheckJNI::GetStringUTFLength,
1953 CheckJNI::GetStringUTFChars,
1954 CheckJNI::ReleaseStringUTFChars,
1955 CheckJNI::GetArrayLength,
1956 CheckJNI::NewObjectArray,
1957 CheckJNI::GetObjectArrayElement,
1958 CheckJNI::SetObjectArrayElement,
1959 CheckJNI::NewBooleanArray,
1960 CheckJNI::NewByteArray,
1961 CheckJNI::NewCharArray,
1962 CheckJNI::NewShortArray,
1963 CheckJNI::NewIntArray,
1964 CheckJNI::NewLongArray,
1965 CheckJNI::NewFloatArray,
1966 CheckJNI::NewDoubleArray,
1967 CheckJNI::GetBooleanArrayElements,
1968 CheckJNI::GetByteArrayElements,
1969 CheckJNI::GetCharArrayElements,
1970 CheckJNI::GetShortArrayElements,
1971 CheckJNI::GetIntArrayElements,
1972 CheckJNI::GetLongArrayElements,
1973 CheckJNI::GetFloatArrayElements,
1974 CheckJNI::GetDoubleArrayElements,
1975 CheckJNI::ReleaseBooleanArrayElements,
1976 CheckJNI::ReleaseByteArrayElements,
1977 CheckJNI::ReleaseCharArrayElements,
1978 CheckJNI::ReleaseShortArrayElements,
1979 CheckJNI::ReleaseIntArrayElements,
1980 CheckJNI::ReleaseLongArrayElements,
1981 CheckJNI::ReleaseFloatArrayElements,
1982 CheckJNI::ReleaseDoubleArrayElements,
1983 CheckJNI::GetBooleanArrayRegion,
1984 CheckJNI::GetByteArrayRegion,
1985 CheckJNI::GetCharArrayRegion,
1986 CheckJNI::GetShortArrayRegion,
1987 CheckJNI::GetIntArrayRegion,
1988 CheckJNI::GetLongArrayRegion,
1989 CheckJNI::GetFloatArrayRegion,
1990 CheckJNI::GetDoubleArrayRegion,
1991 CheckJNI::SetBooleanArrayRegion,
1992 CheckJNI::SetByteArrayRegion,
1993 CheckJNI::SetCharArrayRegion,
1994 CheckJNI::SetShortArrayRegion,
1995 CheckJNI::SetIntArrayRegion,
1996 CheckJNI::SetLongArrayRegion,
1997 CheckJNI::SetFloatArrayRegion,
1998 CheckJNI::SetDoubleArrayRegion,
1999 CheckJNI::RegisterNatives,
2000 CheckJNI::UnregisterNatives,
2001 CheckJNI::MonitorEnter,
2002 CheckJNI::MonitorExit,
2003 CheckJNI::GetJavaVM,
2004 CheckJNI::GetStringRegion,
2005 CheckJNI::GetStringUTFRegion,
2006 CheckJNI::GetPrimitiveArrayCritical,
2007 CheckJNI::ReleasePrimitiveArrayCritical,
2008 CheckJNI::GetStringCritical,
2009 CheckJNI::ReleaseStringCritical,
2010 CheckJNI::NewWeakGlobalRef,
2011 CheckJNI::DeleteWeakGlobalRef,
2012 CheckJNI::ExceptionCheck,
2013 CheckJNI::NewDirectByteBuffer,
2014 CheckJNI::GetDirectBufferAddress,
2015 CheckJNI::GetDirectBufferCapacity,
2016 CheckJNI::GetObjectRefType,
2017};
2018
2019const JNINativeInterface* GetCheckJniNativeInterface() {
2020 return &gCheckNativeInterface;
2021}
2022
2023class CheckJII {
Elliott Hughesba8eee12012-01-24 20:25:24 -08002024 public:
Elliott Hughesa2501992011-08-26 19:39:54 -07002025 static jint DestroyJavaVM(JavaVM* vm) {
Elliott Hughesa0957642011-09-02 14:27:33 -07002026 ScopedCheck sc(vm, false, __FUNCTION__);
Elliott Hughes32ae6e32011-09-27 10:46:50 -07002027 sc.Check(true, "v", vm);
2028 return CHECK_JNI_EXIT("I", BaseVm(vm)->DestroyJavaVM(vm));
Elliott Hughesa2501992011-08-26 19:39:54 -07002029 }
2030
2031 static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
Elliott Hughesa0957642011-09-02 14:27:33 -07002032 ScopedCheck sc(vm, false, __FUNCTION__);
Elliott Hughes32ae6e32011-09-27 10:46:50 -07002033 sc.Check(true, "vpp", vm, p_env, thr_args);
2034 return CHECK_JNI_EXIT("I", BaseVm(vm)->AttachCurrentThread(vm, p_env, thr_args));
Elliott Hughesa2501992011-08-26 19:39:54 -07002035 }
2036
2037 static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
Elliott Hughesa0957642011-09-02 14:27:33 -07002038 ScopedCheck sc(vm, false, __FUNCTION__);
Elliott Hughes32ae6e32011-09-27 10:46:50 -07002039 sc.Check(true, "vpp", vm, p_env, thr_args);
2040 return CHECK_JNI_EXIT("I", BaseVm(vm)->AttachCurrentThreadAsDaemon(vm, p_env, thr_args));
Elliott Hughesa2501992011-08-26 19:39:54 -07002041 }
2042
2043 static jint DetachCurrentThread(JavaVM* vm) {
Elliott Hughesa0957642011-09-02 14:27:33 -07002044 ScopedCheck sc(vm, true, __FUNCTION__);
Elliott Hughes32ae6e32011-09-27 10:46:50 -07002045 sc.Check(true, "v", vm);
2046 return CHECK_JNI_EXIT("I", BaseVm(vm)->DetachCurrentThread(vm));
Elliott Hughesa2501992011-08-26 19:39:54 -07002047 }
2048
2049 static jint GetEnv(JavaVM* vm, void** env, jint version) {
Elliott Hughesa0957642011-09-02 14:27:33 -07002050 ScopedCheck sc(vm, true, __FUNCTION__);
Elliott Hughes83a25322013-03-14 11:18:53 -07002051 sc.Check(true, "vpI", vm);
Elliott Hughes32ae6e32011-09-27 10:46:50 -07002052 return CHECK_JNI_EXIT("I", BaseVm(vm)->GetEnv(vm, env, version));
Elliott Hughesa2501992011-08-26 19:39:54 -07002053 }
2054
2055 private:
Elliott Hughes32ae6e32011-09-27 10:46:50 -07002056 static inline const JNIInvokeInterface* BaseVm(JavaVM* vm) {
Elliott Hughesa2501992011-08-26 19:39:54 -07002057 return reinterpret_cast<JavaVMExt*>(vm)->unchecked_functions;
2058 }
2059};
2060
2061const JNIInvokeInterface gCheckInvokeInterface = {
Ian Rogersef7d42f2014-01-06 12:55:46 -08002062 nullptr, // reserved0
2063 nullptr, // reserved1
2064 nullptr, // reserved2
Elliott Hughesa2501992011-08-26 19:39:54 -07002065 CheckJII::DestroyJavaVM,
2066 CheckJII::AttachCurrentThread,
2067 CheckJII::DetachCurrentThread,
2068 CheckJII::GetEnv,
2069 CheckJII::AttachCurrentThreadAsDaemon
2070};
2071
2072const JNIInvokeInterface* GetCheckJniInvokeInterface() {
2073 return &gCheckInvokeInterface;
2074}
2075
2076} // namespace art