168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers/* 268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * Copyright (C) 2011 The Android Open Source Project 368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * 468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * you may not use this file except in compliance with the License. 668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * You may obtain a copy of the License at 768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * 868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * http://www.apache.org/licenses/LICENSE-2.0 968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * 1068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * Unless required by applicable law or agreed to in writing, software 1168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * distributed under the License is distributed on an "AS IS" BASIS, 1268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * See the License for the specific language governing permissions and 1468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers * limitations under the License. 1568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers */ 1668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 1768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#ifndef ART_RUNTIME_JNI_ENV_EXT_H_ 1868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#define ART_RUNTIME_JNI_ENV_EXT_H_ 1968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 2068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include <jni.h> 2168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 2268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include "base/macros.h" 2368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include "base/mutex.h" 2468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include "indirect_reference_table.h" 2568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include "object_callbacks.h" 2668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include "reference_table.h" 2768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 2868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogersnamespace art { 2968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 3068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogersclass JavaVMExt; 3168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 3268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers// Maximum number of local references in the indirect reference table. The value is arbitrary but 3368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers// low enough that it forces sanity checks. 3468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogersstatic constexpr size_t kLocalsMax = 512; 3568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 3668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogersstruct JNIEnvExt : public JNIEnv { 373f5881fda3606b27e30bf903052c73b03910f90bAndreas Gampe static JNIEnvExt* Create(Thread* self, JavaVMExt* vm); 383f5881fda3606b27e30bf903052c73b03910f90bAndreas Gampe 3968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers ~JNIEnvExt(); 4068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 4168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers void DumpReferenceTables(std::ostream& os) 4268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 4368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 4468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers void SetCheckJniEnabled(bool enabled); 4568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 4668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers void PushFrame(int capacity); 4768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers void PopFrame(); 4868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 4968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers template<typename T> 5068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers T AddLocalReference(mirror::Object* obj) 5168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 5268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 5368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers static Offset SegmentStateOffset(); 5468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 5568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers static Offset LocalRefCookieOffset() { 5668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers return Offset(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie)); 5768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 5868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 5968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers static Offset SelfOffset() { 6068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers return Offset(OFFSETOF_MEMBER(JNIEnvExt, self)); 6168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 6268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 6368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers jobject NewLocalRef(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 6468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers void DeleteLocalRef(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 6568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 6668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers Thread* const self; 6768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers JavaVMExt* const vm; 6868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 6968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers // Cookie used when using the local indirect reference table. 7068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers uint32_t local_ref_cookie; 7168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 7268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers // JNI local references. 7368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers IndirectReferenceTable locals GUARDED_BY(Locks::mutator_lock_); 7468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 7568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers // Stack of cookies corresponding to PushLocalFrame/PopLocalFrame calls. 7668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers // TODO: to avoid leaks (and bugs), we need to clear this vector on entry (or return) 7768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers // to a native method. 7868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers std::vector<uint32_t> stacked_local_ref_cookies; 7968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 8068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers // Frequently-accessed fields cached from JavaVM. 8168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers bool check_jni; 8268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 8368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers // How many nested "critical" JNI calls are we in? 8468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers int critical; 8568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 8668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers // Entered JNI monitors, for bulk exit on thread detach. 8768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers ReferenceTable monitors; 8868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 8968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers // Used by -Xcheck:jni. 9068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers const JNINativeInterface* unchecked_functions; 913f5881fda3606b27e30bf903052c73b03910f90bAndreas Gampe 923f5881fda3606b27e30bf903052c73b03910f90bAndreas Gampe private: 933f5881fda3606b27e30bf903052c73b03910f90bAndreas Gampe // The constructor should not be called directly. It may leave the object in an erronuous state, 943f5881fda3606b27e30bf903052c73b03910f90bAndreas Gampe // and the result needs to be checked. 953f5881fda3606b27e30bf903052c73b03910f90bAndreas Gampe JNIEnvExt(Thread* self, JavaVMExt* vm); 9668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers}; 9768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 9868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers// Used to save and restore the JNIEnvExt state when not going through code created by the JNI 9968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers// compiler. 10068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogersclass ScopedJniEnvLocalRefState { 10168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers public: 10268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers explicit ScopedJniEnvLocalRefState(JNIEnvExt* env) : env_(env) { 10368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers saved_local_ref_cookie_ = env->local_ref_cookie; 10468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers env->local_ref_cookie = env->locals.GetSegmentState(); 10568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 10668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 10768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers ~ScopedJniEnvLocalRefState() { 10868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers env_->locals.SetSegmentState(env_->local_ref_cookie); 10968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers env_->local_ref_cookie = saved_local_ref_cookie_; 11068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers } 11168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 11268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers private: 11368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers JNIEnvExt* const env_; 11468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers uint32_t saved_local_ref_cookie_; 11568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 11668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers DISALLOW_COPY_AND_ASSIGN(ScopedJniEnvLocalRefState); 11768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers}; 11868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 11968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers} // namespace art 12068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 12168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#endif // ART_RUNTIME_JNI_ENV_EXT_H_ 122