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_JAVA_VM_EXT_H_
18 #define ART_RUNTIME_JAVA_VM_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 "reference_table.h"
26 
27 namespace art {
28 
29 namespace mirror {
30   class Array;
31 }  // namespace mirror
32 
33 class ArtMethod;
34 class Libraries;
35 class ParsedOptions;
36 class Runtime;
37 struct RuntimeArgumentMap;
38 
39 class JavaVMExt : public JavaVM {
40  public:
41   JavaVMExt(Runtime* runtime, const RuntimeArgumentMap& runtime_options);
42   ~JavaVMExt();
43 
ForceCopy()44   bool ForceCopy() const {
45     return force_copy_;
46   }
47 
IsCheckJniEnabled()48   bool IsCheckJniEnabled() const {
49     return check_jni_;
50   }
51 
IsTracingEnabled()52   bool IsTracingEnabled() const {
53     return tracing_enabled_;
54   }
55 
GetRuntime()56   Runtime* GetRuntime() const {
57     return runtime_;
58   }
59 
SetCheckJniAbortHook(void (* hook)(void *,const std::string &),void * data)60   void SetCheckJniAbortHook(void (*hook)(void*, const std::string&), void* data) {
61     check_jni_abort_hook_ = hook;
62     check_jni_abort_hook_data_ = data;
63   }
64 
65   // Aborts execution unless there is an abort handler installed in which case it will return. Its
66   // therefore important that callers return after aborting as otherwise code following the abort
67   // will be executed in the abort handler case.
68   void JniAbort(const char* jni_function_name, const char* msg);
69 
70   void JniAbortV(const char* jni_function_name, const char* fmt, va_list ap);
71 
72   void JniAbortF(const char* jni_function_name, const char* fmt, ...)
73       __attribute__((__format__(__printf__, 3, 4)));
74 
75   // If both "-Xcheck:jni" and "-Xjnitrace:" are enabled, we print trace messages
76   // when a native method that matches the -Xjnitrace argument calls a JNI function
77   // such as NewByteArray.
78   // If -verbose:third-party-jni is on, we want to log any JNI function calls
79   // made by a third-party native method.
80   bool ShouldTrace(ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
81 
82   /**
83    * Loads the given shared library. 'path' is an absolute pathname.
84    *
85    * Returns 'true' on success. On failure, sets 'detail' to a
86    * human-readable description of the error.
87    */
88   bool LoadNativeLibrary(JNIEnv* env, const std::string& path, jobject javaLoader,
89                          std::string* error_msg);
90 
91   /**
92    * Returns a pointer to the code for the native method 'm', found
93    * using dlsym(3) on every native library that's been loaded so far.
94    */
95   void* FindCodeForNativeMethod(ArtMethod* m)
96       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
97 
98   void DumpForSigQuit(std::ostream& os)
99       LOCKS_EXCLUDED(Locks::jni_libraries_lock_, globals_lock_, weak_globals_lock_);
100 
101   void DumpReferenceTables(std::ostream& os)
102       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
103 
104   bool SetCheckJniEnabled(bool enabled);
105 
106   void VisitRoots(RootVisitor* visitor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
107 
108   void DisallowNewWeakGlobals() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
109   void AllowNewWeakGlobals() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
110   void EnsureNewWeakGlobalsDisallowed() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
111 
112   jobject AddGlobalRef(Thread* self, mirror::Object* obj)
113       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
114 
115   jweak AddWeakGlobalRef(Thread* self, mirror::Object* obj)
116     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
117 
118   void DeleteGlobalRef(Thread* self, jobject obj);
119 
120   void DeleteWeakGlobalRef(Thread* self, jweak obj);
121 
122   void SweepJniWeakGlobals(IsMarkedCallback* callback, void* arg)
123       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
124 
125   mirror::Object* DecodeGlobal(Thread* self, IndirectRef ref)
126       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
127 
128   void UpdateGlobal(Thread* self, IndirectRef ref, mirror::Object* result)
129       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
130       LOCKS_EXCLUDED(globals_lock_);
131 
132   mirror::Object* DecodeWeakGlobal(Thread* self, IndirectRef ref)
133       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
134 
135   void UpdateWeakGlobal(Thread* self, IndirectRef ref, mirror::Object* result)
136       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
137       LOCKS_EXCLUDED(weak_globals_lock_);
138 
GetUncheckedFunctions()139   const JNIInvokeInterface* GetUncheckedFunctions() const {
140     return unchecked_functions_;
141   }
142 
143   void TrimGlobals() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
144       LOCKS_EXCLUDED(globals_lock_);
145 
146  private:
147   Runtime* const runtime_;
148 
149   // Used for testing. By default, we'll LOG(FATAL) the reason.
150   void (*check_jni_abort_hook_)(void* data, const std::string& reason);
151   void* check_jni_abort_hook_data_;
152 
153   // Extra checking.
154   bool check_jni_;
155   bool force_copy_;
156   const bool tracing_enabled_;
157 
158   // Extra diagnostics.
159   const std::string trace_;
160 
161   // JNI global references.
162   ReaderWriterMutex globals_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
163   // Not guarded by globals_lock since we sometimes use SynchronizedGet in Thread::DecodeJObject.
164   IndirectReferenceTable globals_;
165 
166   std::unique_ptr<Libraries> libraries_ GUARDED_BY(Locks::jni_libraries_lock_);
167 
168   // Used by -Xcheck:jni.
169   const JNIInvokeInterface* const unchecked_functions_;
170 
171   // JNI weak global references.
172   Mutex weak_globals_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
173   // Since weak_globals_ contain weak roots, be careful not to
174   // directly access the object references in it. Use Get() with the
175   // read barrier enabled.
176   IndirectReferenceTable weak_globals_ GUARDED_BY(weak_globals_lock_);
177   bool allow_new_weak_globals_ GUARDED_BY(weak_globals_lock_);
178   ConditionVariable weak_globals_add_condition_ GUARDED_BY(weak_globals_lock_);
179 
180   DISALLOW_COPY_AND_ASSIGN(JavaVMExt);
181 };
182 
183 }  // namespace art
184 
185 #endif  // ART_RUNTIME_JAVA_VM_EXT_H_
186