jni_internal.h revision 94f7b49578b6aaa80de8ffed230648d601393905
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
38namespace art {
39namespace mirror {
40  class ArtField;
41  class ArtMethod;
42  class ClassLoader;
43}  // namespace mirror
44union JValue;
45class Libraries;
46class ParsedOptions;
47class Runtime;
48class ScopedObjectAccess;
49template<class T> class Handle;
50class Thread;
51
52void JniAbortF(const char* jni_function_name, const char* fmt, ...)
53    __attribute__((__format__(__printf__, 2, 3)));
54void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
55                           jint method_count);
56
57int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause);
58
59class 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  // Used to hold references to pinned primitive arrays.
116  Mutex pins_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
117  ReferenceTable pin_table GUARDED_BY(pins_lock);
118
119  // JNI global references.
120  ReaderWriterMutex globals_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
121  // Not guarded by globals_lock since we sometimes use SynchronizedGet in Thread::DecodeJObject.
122  IndirectReferenceTable globals;
123
124  Mutex libraries_lock DEFAULT_MUTEX_ACQUIRED_AFTER;
125  Libraries* libraries GUARDED_BY(libraries_lock);
126
127  // Used by -Xcheck:jni.
128  const JNIInvokeInterface* unchecked_functions;
129
130 private:
131  // TODO: Make the other members of this class also private.
132  // JNI weak global references.
133  Mutex weak_globals_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
134  // Since weak_globals_ contain weak roots, be careful not to
135  // directly access the object references in it. Use Get() with the
136  // read barrier enabled.
137  IndirectReferenceTable weak_globals_ GUARDED_BY(weak_globals_lock_);
138  bool allow_new_weak_globals_ GUARDED_BY(weak_globals_lock_);
139  ConditionVariable weak_globals_add_condition_ GUARDED_BY(weak_globals_lock_);
140};
141
142struct JNIEnvExt : public JNIEnv {
143  JNIEnvExt(Thread* self, JavaVMExt* vm);
144  ~JNIEnvExt();
145
146  void DumpReferenceTables(std::ostream& os)
147      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
148
149  void SetCheckJniEnabled(bool enabled);
150
151  void PushFrame(int capacity);
152  void PopFrame();
153
154  template<typename T>
155  T AddLocalReference(mirror::Object* obj)
156      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
157
158  static Offset SegmentStateOffset();
159
160  static Offset LocalRefCookieOffset() {
161    return Offset(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie));
162  }
163
164  static Offset SelfOffset() {
165    return Offset(OFFSETOF_MEMBER(JNIEnvExt, self));
166  }
167
168  jobject NewLocalRef(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
169  void DeleteLocalRef(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
170
171  Thread* const self;
172  JavaVMExt* vm;
173
174  // Cookie used when using the local indirect reference table.
175  uint32_t local_ref_cookie;
176
177  // JNI local references.
178  IndirectReferenceTable locals GUARDED_BY(Locks::mutator_lock_);
179
180  // Stack of cookies corresponding to PushLocalFrame/PopLocalFrame calls.
181  // TODO: to avoid leaks (and bugs), we need to clear this vector on entry (or return)
182  // to a native method.
183  std::vector<uint32_t> stacked_local_ref_cookies;
184
185  // Frequently-accessed fields cached from JavaVM.
186  bool check_jni;
187
188  // How many nested "critical" JNI calls are we in?
189  int critical;
190
191  // Entered JNI monitors, for bulk exit on thread detach.
192  ReferenceTable monitors;
193
194  // Used by -Xcheck:jni.
195  const JNINativeInterface* unchecked_functions;
196};
197
198const JNINativeInterface* GetCheckJniNativeInterface();
199const JNIInvokeInterface* GetCheckJniInvokeInterface();
200
201// Used to save and restore the JNIEnvExt state when not going through code created by the JNI
202// compiler
203class ScopedJniEnvLocalRefState {
204 public:
205  explicit ScopedJniEnvLocalRefState(JNIEnvExt* env) : env_(env) {
206    saved_local_ref_cookie_ = env->local_ref_cookie;
207    env->local_ref_cookie = env->locals.GetSegmentState();
208  }
209
210  ~ScopedJniEnvLocalRefState() {
211    env_->locals.SetSegmentState(env_->local_ref_cookie);
212    env_->local_ref_cookie = saved_local_ref_cookie_;
213  }
214
215 private:
216  JNIEnvExt* env_;
217  uint32_t saved_local_ref_cookie_;
218  DISALLOW_COPY_AND_ASSIGN(ScopedJniEnvLocalRefState);
219};
220
221}  // namespace art
222
223std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs);
224#endif  // ART_RUNTIME_JNI_INTERNAL_H_
225