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