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