1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_JNI_ENV_EXT_H_ 18 #define ART_RUNTIME_JNI_ENV_EXT_H_ 19 20 #include <jni.h> 21 22 #include "base/macros.h" 23 #include "base/mutex.h" 24 #include "indirect_reference_table.h" 25 #include "object_callbacks.h" 26 #include "reference_table.h" 27 28 namespace art { 29 30 class JavaVMExt; 31 32 // Maximum number of local references in the indirect reference table. The value is arbitrary but 33 // low enough that it forces sanity checks. 34 static constexpr size_t kLocalsMax = 512; 35 36 struct JNIEnvExt : public JNIEnv { 37 static JNIEnvExt* Create(Thread* self, JavaVMExt* vm); 38 39 ~JNIEnvExt(); 40 41 void DumpReferenceTables(std::ostream& os) 42 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 43 44 void SetCheckJniEnabled(bool enabled); 45 46 void PushFrame(int capacity); 47 void PopFrame(); 48 49 template<typename T> 50 T AddLocalReference(mirror::Object* obj) 51 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 52 53 static Offset SegmentStateOffset(); 54 LocalRefCookieOffsetJNIEnvExt55 static Offset LocalRefCookieOffset() { 56 return Offset(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie)); 57 } 58 SelfOffsetJNIEnvExt59 static Offset SelfOffset() { 60 return Offset(OFFSETOF_MEMBER(JNIEnvExt, self)); 61 } 62 63 jobject NewLocalRef(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 64 void DeleteLocalRef(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 65 66 Thread* const self; 67 JavaVMExt* const vm; 68 69 // Cookie used when using the local indirect reference table. 70 uint32_t local_ref_cookie; 71 72 // JNI local references. 73 IndirectReferenceTable locals GUARDED_BY(Locks::mutator_lock_); 74 75 // Stack of cookies corresponding to PushLocalFrame/PopLocalFrame calls. 76 // TODO: to avoid leaks (and bugs), we need to clear this vector on entry (or return) 77 // to a native method. 78 std::vector<uint32_t> stacked_local_ref_cookies; 79 80 // Frequently-accessed fields cached from JavaVM. 81 bool check_jni; 82 83 // How many nested "critical" JNI calls are we in? 84 int critical; 85 86 // Entered JNI monitors, for bulk exit on thread detach. 87 ReferenceTable monitors; 88 89 // Used by -Xcheck:jni. 90 const JNINativeInterface* unchecked_functions; 91 92 private: 93 // The constructor should not be called directly. It may leave the object in an erronuous state, 94 // and the result needs to be checked. 95 JNIEnvExt(Thread* self, JavaVMExt* vm); 96 }; 97 98 // Used to save and restore the JNIEnvExt state when not going through code created by the JNI 99 // compiler. 100 class ScopedJniEnvLocalRefState { 101 public: ScopedJniEnvLocalRefState(JNIEnvExt * env)102 explicit ScopedJniEnvLocalRefState(JNIEnvExt* env) : env_(env) { 103 saved_local_ref_cookie_ = env->local_ref_cookie; 104 env->local_ref_cookie = env->locals.GetSegmentState(); 105 } 106 ~ScopedJniEnvLocalRefState()107 ~ScopedJniEnvLocalRefState() { 108 env_->locals.SetSegmentState(env_->local_ref_cookie); 109 env_->local_ref_cookie = saved_local_ref_cookie_; 110 } 111 112 private: 113 JNIEnvExt* const env_; 114 uint32_t saved_local_ref_cookie_; 115 116 DISALLOW_COPY_AND_ASSIGN(ScopedJniEnvLocalRefState); 117 }; 118 119 } // namespace art 120 121 #endif // ART_RUNTIME_JNI_ENV_EXT_H_ 122