• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_INTERNAL_H_
18 #define ART_RUNTIME_JNI_INTERNAL_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 #include <iosfwd>
29 #include <string>
30 
31 #ifndef NATIVE_METHOD
32 #define NATIVE_METHOD(className, functionName, signature) \
33   { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) }
34 #endif
35 #define REGISTER_NATIVE_METHODS(jni_class_name) \
36   RegisterNativeMethods(env, jni_class_name, gMethods, arraysize(gMethods))
37 
38 namespace art {
39 namespace mirror {
40   class ArtField;
41   class ArtMethod;
42   class ClassLoader;
43 }  // namespace mirror
44 union JValue;
45 class Libraries;
46 class ParsedOptions;
47 class Runtime;
48 class ScopedObjectAccess;
49 template<class T> class Handle;
50 class Thread;
51 
52 void JniAbortF(const char* jni_function_name, const char* fmt, ...)
53     __attribute__((__format__(__printf__, 2, 3)));
54 void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
55                            jint method_count);
56 
57 int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause);
58 
59 class JavaVMExt : public JavaVM {
60  public:
61   JavaVMExt(Runtime* runtime, ParsedOptions* options);
62   ~JavaVMExt();
63 
64   /**
65    * Loads the given shared library. 'path' is an absolute pathname.
66    *
67    * Returns 'true' on success. On failure, sets 'detail' to a
68    * human-readable description of the error.
69    */
70   bool LoadNativeLibrary(const std::string& path, Handle<mirror::ClassLoader> class_loader,
71                          std::string* detail)
72       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
73 
74   /**
75    * Returns a pointer to the code for the native method 'm', found
76    * using dlsym(3) on every native library that's been loaded so far.
77    */
78   void* FindCodeForNativeMethod(mirror::ArtMethod* m)
79       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
80 
81   void DumpForSigQuit(std::ostream& os);
82 
83   void DumpReferenceTables(std::ostream& os)
84       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
85 
86   void SetCheckJniEnabled(bool enabled);
87 
88   void VisitRoots(RootCallback* callback, void* arg)
89       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
90 
91   void DisallowNewWeakGlobals() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
92   void AllowNewWeakGlobals() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
93   jweak AddWeakGlobalReference(Thread* self, mirror::Object* obj)
94     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
95   void DeleteWeakGlobalRef(Thread* self, jweak obj)
96     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
97   void SweepJniWeakGlobals(IsMarkedCallback* callback, void* arg)
98       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
99   mirror::Object* DecodeWeakGlobal(Thread* self, IndirectRef ref)
100       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
101 
102   Runtime* runtime;
103 
104   // Used for testing. By default, we'll LOG(FATAL) the reason.
105   void (*check_jni_abort_hook)(void* data, const std::string& reason);
106   void* check_jni_abort_hook_data;
107 
108   // Extra checking.
109   bool check_jni;
110   bool force_copy;
111 
112   // Extra diagnostics.
113   std::string trace;
114 
115   // JNI global references.
116   ReaderWriterMutex globals_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
117   // Not guarded by globals_lock since we sometimes use SynchronizedGet in Thread::DecodeJObject.
118   IndirectReferenceTable globals;
119 
120   Mutex libraries_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
121   Libraries* libraries GUARDED_BY(libraries_lock);
122 
123   // Used by -Xcheck:jni.
124   const JNIInvokeInterface* unchecked_functions;
125 
126  private:
127   // TODO: Make the other members of this class also private.
128   // JNI weak global references.
129   Mutex weak_globals_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
130   // Since weak_globals_ contain weak roots, be careful not to
131   // directly access the object references in it. Use Get() with the
132   // read barrier enabled.
133   IndirectReferenceTable weak_globals_ GUARDED_BY(weak_globals_lock_);
134   bool allow_new_weak_globals_ GUARDED_BY(weak_globals_lock_);
135   ConditionVariable weak_globals_add_condition_ GUARDED_BY(weak_globals_lock_);
136 };
137 
138 struct JNIEnvExt : public JNIEnv {
139   JNIEnvExt(Thread* self, JavaVMExt* vm);
140   ~JNIEnvExt();
141 
142   void DumpReferenceTables(std::ostream& os)
143       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
144 
145   void SetCheckJniEnabled(bool enabled);
146 
147   void PushFrame(int capacity);
148   void PopFrame();
149 
150   template<typename T>
151   T AddLocalReference(mirror::Object* obj)
152       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
153 
154   static Offset SegmentStateOffset();
155 
LocalRefCookieOffsetJNIEnvExt156   static Offset LocalRefCookieOffset() {
157     return Offset(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie));
158   }
159 
SelfOffsetJNIEnvExt160   static Offset SelfOffset() {
161     return Offset(OFFSETOF_MEMBER(JNIEnvExt, self));
162   }
163 
164   jobject NewLocalRef(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
165   void DeleteLocalRef(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
166 
167   Thread* const self;
168   JavaVMExt* vm;
169 
170   // Cookie used when using the local indirect reference table.
171   uint32_t local_ref_cookie;
172 
173   // JNI local references.
174   IndirectReferenceTable locals GUARDED_BY(Locks::mutator_lock_);
175 
176   // Stack of cookies corresponding to PushLocalFrame/PopLocalFrame calls.
177   // TODO: to avoid leaks (and bugs), we need to clear this vector on entry (or return)
178   // to a native method.
179   std::vector<uint32_t> stacked_local_ref_cookies;
180 
181   // Frequently-accessed fields cached from JavaVM.
182   bool check_jni;
183 
184   // How many nested "critical" JNI calls are we in?
185   int critical;
186 
187   // Entered JNI monitors, for bulk exit on thread detach.
188   ReferenceTable monitors;
189 
190   // Used by -Xcheck:jni.
191   const JNINativeInterface* unchecked_functions;
192 };
193 
194 const JNINativeInterface* GetCheckJniNativeInterface();
195 const JNIInvokeInterface* GetCheckJniInvokeInterface();
196 
197 // Used to save and restore the JNIEnvExt state when not going through code created by the JNI
198 // compiler
199 class ScopedJniEnvLocalRefState {
200  public:
ScopedJniEnvLocalRefState(JNIEnvExt * env)201   explicit ScopedJniEnvLocalRefState(JNIEnvExt* env) : env_(env) {
202     saved_local_ref_cookie_ = env->local_ref_cookie;
203     env->local_ref_cookie = env->locals.GetSegmentState();
204   }
205 
~ScopedJniEnvLocalRefState()206   ~ScopedJniEnvLocalRefState() {
207     env_->locals.SetSegmentState(env_->local_ref_cookie);
208     env_->local_ref_cookie = saved_local_ref_cookie_;
209   }
210 
211  private:
212   JNIEnvExt* env_;
213   uint32_t saved_local_ref_cookie_;
214   DISALLOW_COPY_AND_ASSIGN(ScopedJniEnvLocalRefState);
215 };
216 
217 }  // namespace art
218 
219 std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs);
220 #endif  // ART_RUNTIME_JNI_INTERNAL_H_
221