12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
16df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers
17578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "jni_internal.h"
182ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
190af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include <dlfcn.h>
2079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
2179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes#include <cstdarg>
22700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory>
230af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include <utility>
240af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes#include <vector>
252ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
26ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers#include "atomic.h"
275369c40f75fdcb1be7a7c06db212ce965c83a164Mathieu Chartier#include "base/allocator.h"
2807ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h"
2976b6167407c2b6f5d40ad895b2793a6b037f54b2Elliott Hughes#include "base/mutex.h"
301aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h"
319837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers#include "class_linker-inl.h"
324f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
331f24296c7c8a6501ee2388c0d20b48f471b48660Mathieu Chartier#include "fault_handler.h"
3494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#include "gc_root.h"
351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/accounting/card_table-inl.h"
36c56057e40938c587a74984651a510e320a8cb4fdMathieu Chartier#include "indirect_reference_table-inl.h"
373dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao#include "interpreter/interpreter.h"
38ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro#include "jni.h"
39ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_field-inl.h"
40ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method-inl.h"
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h"
422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h"
432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h"
45b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include "mirror/string-inl.h"
462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/throwable.h"
476d031046eeb5e9f62b657df0695b752e1d0aa583jgu#include "nativebridge/native_bridge.h"
48491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom#include "parsed_options.h"
4953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#include "reflection.h"
502ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro#include "runtime.h"
51a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h"
5200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h"
53a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "ScopedLocalRef.h"
542ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro#include "thread.h"
552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "utf.h"
56eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "well_known_classes.h"
57df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers
58bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughesnamespace art {
59bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes
607934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kMonitorsInitial = 32;  // Arbitrary.
617934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kMonitorsMax = 4096;  // Arbitrary sanity check.
622ced6a534157d5d963693346904389c19775d2daElliott Hughes
637934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kLocalsInitial = 64;  // Arbitrary.
647934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kLocalsMax = 512;  // Arbitrary sanity check.
652ced6a534157d5d963693346904389c19775d2daElliott Hughes
667934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic size_t gGlobalsInitial = 512;  // Arbitrary.
677934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic size_t gGlobalsMax = 51200;  // Arbitrary sanity check. (Must fit in 16 bits.)
682ced6a534157d5d963693346904389c19775d2daElliott Hughes
697934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kWeakGlobalsInitial = 16;  // Arbitrary.
707934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstromstatic const size_t kWeakGlobalsMax = 51200;  // Arbitrary sanity check. (Must fit in 16 bits.)
71df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers
72e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierstatic jweak AddWeakGlobalReference(ScopedObjectAccess& soa, mirror::Object* obj)
73b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
74c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  return soa.Vm()->AddWeakGlobalReference(soa.Self(), obj);
7545619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers}
7645619fcc01fb6db1ac9481a91608eb46f90829e4Ian Rogers
7719c5d3786894af707d8079231105bca1b7dcd096Jeff Haostatic bool IsBadJniVersion(int version) {
7819c5d3786894af707d8079231105bca1b7dcd096Jeff Hao  // We don't support JNI_VERSION_1_1. These are the only other valid versions.
7919c5d3786894af707d8079231105bca1b7dcd096Jeff Hao  return version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 && version != JNI_VERSION_1_6;
8019c5d3786894af707d8079231105bca1b7dcd096Jeff Hao}
8119c5d3786894af707d8079231105bca1b7dcd096Jeff Hao
826b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
836b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// separated with slashes but aren't wrapped with "L;" like regular descriptors
846b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
856b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// exception; there the "L;" must be present ("[La/b/C;"). Historically we've
866b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// supported names with dots too (such as "a.b.C").
870571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersstatic std::string NormalizeJniClassDescriptor(const char* name) {
886b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  std::string result;
896b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  // Add the missing "L;" if necessary.
906b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  if (name[0] == '[') {
916b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes    result = name;
926b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  } else {
936b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes    result += 'L';
946b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes    result += name;
956b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes    result += ';';
966b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  }
976b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  // Rewrite '.' as '/' for backwards compatibility.
98a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  if (result.find('.') != std::string::npos) {
99a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes    LOG(WARNING) << "Call to JNI FindClass with dots in name: "
100a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes                 << "\"" << name << "\"";
101a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes    std::replace(result.begin(), result.end(), '.', '/');
1026b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  }
1036b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  return result;
1046b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes}
1056b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes
106e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierstatic void ThrowNoSuchMethodError(ScopedObjectAccess& soa, mirror::Class* c,
10700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                   const char* name, const char* sig, const char* kind)
108b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
10962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
110cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers  std::string temp;
11162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchMethodError;",
11262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                 "no %s method \"%s.%s%s\"",
113cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers                                 kind, c->GetDescriptor(&temp), name, sig);
11414134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes}
11514134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes
116fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzstatic void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa, mirror::Class* c,
117fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                                         const char* kind, jint idx, bool return_errors)
118fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
119fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  LOG(return_errors ? ERROR : FATAL) << "Failed to register native method in "
120fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      << PrettyDescriptor(c) << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
121fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      << ": " << kind << " is null at index " << idx;
122fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
123fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchMethodError;",
124fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                                 "%s is null at index %d", kind, idx);
125fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz}
126fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
127c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierstatic mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass)
128c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
129c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  if (LIKELY(klass->IsInitialized())) {
130c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    return klass;
131c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  }
132eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  StackHandleScope<1> hs(self);
133eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  Handle<mirror::Class> h_klass(hs.NewHandle(klass));
134eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(h_klass, true, true)) {
135c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    return nullptr;
136c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  }
137eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  return h_klass.Get();
138c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier}
139c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier
14000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
14100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                              const char* name, const char* sig, bool is_static)
142b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
143e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class));
144c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  if (c == nullptr) {
145c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    return nullptr;
146cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
147e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::ArtMethod* method = nullptr;
148cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  if (is_static) {
149cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    method = c->FindDirectMethod(name, sig);
150004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  } else if (c->IsInterface()) {
151004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom    method = c->FindInterfaceMethod(name, sig);
152cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  } else {
153cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    method = c->FindVirtualMethod(name, sig);
154e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (method == nullptr) {
155cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // No virtual method matching the signature.  Search declared
156cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // private methods and constructors.
157cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      method = c->FindDeclaredDirectMethod(name, sig);
158cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
159cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
160e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (method == nullptr || method->IsStatic() != is_static) {
16100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
162e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return nullptr;
163cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
16400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return soa.EncodeMethod(method);
165ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro}
166ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
167e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierstatic mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
168b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
169e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
170ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
171ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
172ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers    return soa.Self()->GetClassLoaderOverride();
17300fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom  }
174ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  // If we have a method, use its ClassLoader for context.
175e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (method != nullptr) {
176ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    return method->GetDeclaringClass()->GetClassLoader();
177ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  }
178ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  // We don't have a method, so try to use the system ClassLoader.
179e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::ClassLoader* class_loader =
180e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
181e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (class_loader != nullptr) {
182ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    return class_loader;
183ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  }
184ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  // See if the override ClassLoader is set for gtests.
185ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  class_loader = soa.Self()->GetClassLoaderOverride();
186e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (class_loader != nullptr) {
187a1ce1fef2d49d1d537776a5308ace7102a815fe5Brian Carlstrom    // If so, CommonCompilerTest should have set UseCompileTimeClassPath.
188ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    CHECK(Runtime::Current()->UseCompileTimeClassPath());
189ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    return class_loader;
190ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  }
191ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  // Use the BOOTCLASSPATH.
192e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  return nullptr;
19300fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom}
19400fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom
19500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
19600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                            const char* sig, bool is_static)
197b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
198eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  StackHandleScope<2> hs(soa.Self());
199eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  Handle<mirror::Class> c(
200eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class))));
201eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  if (c.Get() == nullptr) {
202c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    return nullptr;
203cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
204e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::ArtField* field = nullptr;
205e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::Class* field_type;
2060cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2070cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  if (sig[1] != '\0') {
208eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
2099837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers    field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
2100cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  } else {
2110cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    field_type = class_linker->FindPrimitiveClass(*sig);
2120cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
213e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (field_type == nullptr) {
2140cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // Failed to find type from the signature of the field.
21500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    DCHECK(soa.Self()->IsExceptionPending());
21662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    ThrowLocation throw_location;
217eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    StackHandleScope<1> hs(soa.Self());
218eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    Handle<mirror::Throwable> cause(hs.NewHandle(soa.Self()->GetException(&throw_location)));
21900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Self()->ClearException();
220cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers    std::string temp;
22162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
222491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                                   "no type \"%s\" found and so no field \"%s\" "
223491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                                   "could be found in class \"%s\" or its superclasses", sig, name,
224cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers                                   c->GetDescriptor(&temp));
225eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    soa.Self()->GetException(nullptr)->SetCause(cause.Get());
226e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return nullptr;
2270cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
228cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers  std::string temp;
229cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  if (is_static) {
230f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier    field = mirror::Class::FindStaticField(soa.Self(), c, name,
231cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers                                           field_type->GetDescriptor(&temp));
2324dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  } else {
233cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers    field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
2344dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
235e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (field == nullptr) {
23662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
23762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
23862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                   "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
239cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers                                   sig, name, c->GetDescriptor(&temp));
240e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return nullptr;
241cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
24200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return soa.EncodeField(field);
243ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro}
244ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
245e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierstatic void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
24600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        jsize length, const char* identifier)
247b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
24854e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes  std::string type(PrettyTypeOf(array));
24962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
25062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayIndexOutOfBoundsException;",
25162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                 "%s offset=%d length=%d %s.length=%d",
25262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                 type.c_str(), start, length, identifier, array->GetLength());
253814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
2540571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
25500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
25600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        jsize array_length)
257b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
25862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
25962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/StringIndexOutOfBoundsException;",
26062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                 "offset=%d length=%d string.length()=%d", start, length,
26162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                 array_length);
262b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
263814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
26400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersint ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
265b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    LOCKS_EXCLUDED(Locks::mutator_lock_) {
26600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Turn the const char* into a java.lang.String.
26700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
268e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (msg != nullptr && s.get() == nullptr) {
26900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return JNI_ERR;
270814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  }
271814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
27200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Choose an appropriate constructor and set up the arguments.
27300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jvalue args[2];
27400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const char* signature;
275e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (msg == nullptr && cause == nullptr) {
27600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    signature = "()V";
277e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  } else if (msg != nullptr && cause == nullptr) {
27800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    signature = "(Ljava/lang/String;)V";
27900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    args[0].l = s.get();
280e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  } else if (msg == nullptr && cause != nullptr) {
28100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    signature = "(Ljava/lang/Throwable;)V";
28200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    args[0].l = cause;
283814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  } else {
28400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
28500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    args[0].l = s.get();
28600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    args[1].l = cause;
28700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
28800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
289e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (mid == nullptr) {
290ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers    ScopedObjectAccess soa(env);
29100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    LOG(ERROR) << "No <init>" << signature << " in "
292e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        << PrettyClass(soa.Decode<mirror::Class*>(exception_class));
29300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return JNI_ERR;
294814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  }
295a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes
296e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  ScopedLocalRef<jthrowable> exception(
297e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
298e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (exception.get() == nullptr) {
29900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return JNI_ERR;
30000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
301ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers  ScopedObjectAccess soa(env);
30262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
303e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  soa.Self()->SetException(throw_location, soa.Decode<mirror::Throwable*>(exception.get()));
30400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return JNI_OK;
305a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes}
306a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes
307462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughesstatic jint JII_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) {
308e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (vm == nullptr || p_env == nullptr) {
3097577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    return JNI_ERR;
3107577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  }
3117577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
312462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  // Return immediately if we're already attached.
313cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes  Thread* self = Thread::Current();
314e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (self != nullptr) {
315cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes    *p_env = self->GetJniEnv();
316cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes    return JNI_OK;
317cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes  }
318cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes
319cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes  Runtime* runtime = reinterpret_cast<JavaVMExt*>(vm)->runtime;
320cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes
321cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes  // No threads allowed in zygote mode.
322cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes  if (runtime->IsZygote()) {
323cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes    LOG(ERROR) << "Attempt to attach a thread in the zygote";
324cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes    return JNI_ERR;
325cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes  }
326cac6cc72c3331257fa6437b36a131e5d551e2f3cElliott Hughes
327462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes  JavaVMAttachArgs* args = static_cast<JavaVMAttachArgs*>(raw_args);
328e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  const char* thread_name = nullptr;
329e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  jobject thread_group = nullptr;
330e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (args != nullptr) {
33183a25328c595975097cf3948451088cbfc64fc09Elliott Hughes    if (IsBadJniVersion(args->version)) {
33283a25328c595975097cf3948451088cbfc64fc09Elliott Hughes      LOG(ERROR) << "Bad JNI version passed to "
33383a25328c595975097cf3948451088cbfc64fc09Elliott Hughes                 << (as_daemon ? "AttachCurrentThreadAsDaemon" : "AttachCurrentThread") << ": "
33483a25328c595975097cf3948451088cbfc64fc09Elliott Hughes                 << args->version;
33583a25328c595975097cf3948451088cbfc64fc09Elliott Hughes      return JNI_EVERSION;
3368692215f793cbf8be9c3d25a705074ca877e09b8Brian Carlstrom    }
337462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes    thread_name = args->name;
338365c10235438607541fa2259a5fec48061b90bd8Ian Rogers    thread_group = args->group;
3397577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  }
3407577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
341664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier  if (!runtime->AttachCurrentThread(thread_name, as_daemon, thread_group, !runtime->IsCompiler())) {
342e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    *p_env = nullptr;
343120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers    return JNI_ERR;
344120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers  } else {
345120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers    *p_env = Thread::Current()->GetJniEnv();
346120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers    return JNI_OK;
347120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers  }
3487577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
3497577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
35079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughesclass SharedLibrary {
35179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes public:
352e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  SharedLibrary(const std::string& path, void* handle, mirror::Object* class_loader)
35379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      : path_(path),
35479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes        handle_(handle),
355355383f61d28f2dc8072fbde2639c80627adf16dYong WU        needs_native_bridge_(false),
35694f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi        class_loader_(GcRoot<mirror::Object>(class_loader)),
3578daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes        jni_on_load_lock_("JNI_OnLoad lock"),
358c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers        jni_on_load_cond_("JNI_OnLoad condition variable", jni_on_load_lock_),
359d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers        jni_on_load_thread_id_(Thread::Current()->GetThreadId()),
36079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes        jni_on_load_result_(kPending) {
36179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
36279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
363ea2e1bd713ca8295ba4fcd01e77a3ce532ea61e4Hiroshi Yamauchi  mirror::Object* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
36494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi    return class_loader_.Read();
36579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
36679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
36779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  std::string GetPath() {
36879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    return path_;
36979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
37079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
37179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  /*
3721bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes   * Check the result of an earlier call to JNI_OnLoad on this library.
3731bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes   * If the call has not yet finished in another thread, wait for it.
37479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes   */
37500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  bool CheckOnLoadResult()
37600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      LOCKS_EXCLUDED(jni_on_load_lock_)
377b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
37879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    Thread* self = Thread::Current();
37900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
38000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    bool okay;
38100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    {
38250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers      MutexLock mu(self, jni_on_load_lock_);
38300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
384d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers      if (jni_on_load_thread_id_ == self->GetThreadId()) {
38500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        // Check this so we don't end up waiting for ourselves.  We need to return "true" so the
38600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        // caller can continue.
38700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        LOG(INFO) << *self << " recursive attempt to load library " << "\"" << path_ << "\"";
38800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        okay = true;
38900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      } else {
39000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        while (jni_on_load_result_ == kPending) {
39100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers          VLOG(jni) << "[" << *self << " waiting for \"" << path_ << "\" " << "JNI_OnLoad...]";
392c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers          jni_on_load_cond_.Wait(self);
39300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        }
39479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
39500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        okay = (jni_on_load_result_ == kOkay);
39600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        VLOG(jni) << "[Earlier JNI_OnLoad for \"" << path_ << "\" "
39700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers            << (okay ? "succeeded" : "failed") << "]";
39800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      }
39979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    }
40000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    self->TransitionFromSuspendedToRunnable();
40179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    return okay;
40279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
40379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
40400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  void SetResult(bool result) LOCKS_EXCLUDED(jni_on_load_lock_) {
405c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers    Thread* self = Thread::Current();
406c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers    MutexLock mu(self, jni_on_load_lock_);
407f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes
40879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    jni_on_load_result_ = result ? kOkay : kFailed;
409dcc247493fd8fb243e335c3ec08e5e625896a47cElliott Hughes    jni_on_load_thread_id_ = 0;
41079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
41179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // Broadcast a wakeup to anybody sleeping on the condition variable.
412c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers    jni_on_load_cond_.Broadcast(self);
41379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
41479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
415355383f61d28f2dc8072fbde2639c80627adf16dYong WU  void SetNeedsNativeBridge() {
416355383f61d28f2dc8072fbde2639c80627adf16dYong WU    needs_native_bridge_ = true;
417355383f61d28f2dc8072fbde2639c80627adf16dYong WU  }
418355383f61d28f2dc8072fbde2639c80627adf16dYong WU
419355383f61d28f2dc8072fbde2639c80627adf16dYong WU  bool NeedsNativeBridge() const {
420355383f61d28f2dc8072fbde2639c80627adf16dYong WU    return needs_native_bridge_;
421355383f61d28f2dc8072fbde2639c80627adf16dYong WU  }
422355383f61d28f2dc8072fbde2639c80627adf16dYong WU
42379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  void* FindSymbol(const std::string& symbol_name) {
42479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    return dlsym(handle_, symbol_name.c_str());
42579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
42679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
427355383f61d28f2dc8072fbde2639c80627adf16dYong WU  void* FindSymbolWithNativeBridge(const std::string& symbol_name, mirror::ArtMethod* m)
428355383f61d28f2dc8072fbde2639c80627adf16dYong WU      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
429355383f61d28f2dc8072fbde2639c80627adf16dYong WU    CHECK(NeedsNativeBridge());
430355383f61d28f2dc8072fbde2639c80627adf16dYong WU
431355383f61d28f2dc8072fbde2639c80627adf16dYong WU    uint32_t len = 0;
432355383f61d28f2dc8072fbde2639c80627adf16dYong WU    const char* shorty = nullptr;
433355383f61d28f2dc8072fbde2639c80627adf16dYong WU    if (m != nullptr) {
434355383f61d28f2dc8072fbde2639c80627adf16dYong WU      shorty = m->GetShorty(&len);
435355383f61d28f2dc8072fbde2639c80627adf16dYong WU    }
43693de4273d72a2558a7b3423547b5074cd76c5796Calin Juravle    return android::NativeBridgeGetTrampoline(handle_, symbol_name.c_str(), shorty, len);
437355383f61d28f2dc8072fbde2639c80627adf16dYong WU  }
438355383f61d28f2dc8072fbde2639c80627adf16dYong WU
43983c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier  void VisitRoots(RootCallback* visitor, void* arg) {
44012f7423a2bb4bfab76700d84eb6d4338d211983aMathieu Chartier    class_loader_.VisitRootIfNonNull(visitor, arg, RootInfo(kRootVMInternal));
4418f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier  }
4428f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier
44379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes private:
44479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  enum JNI_OnLoadState {
44579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    kPending,
44679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    kFailed,
44779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    kOkay,
44879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  };
44979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
45079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  // Path to library "/system/lib/libjni.so".
45179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  std::string path_;
45279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
45379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  // The void* returned by dlopen(3).
45479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  void* handle_;
45579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
456355383f61d28f2dc8072fbde2639c80627adf16dYong WU  // True if a native bridge is required.
457355383f61d28f2dc8072fbde2639c80627adf16dYong WU  bool needs_native_bridge_;
458355383f61d28f2dc8072fbde2639c80627adf16dYong WU
45979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  // The ClassLoader this library is associated with.
46094f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi  GcRoot<mirror::Object> class_loader_;
46179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
46279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  // Guards remaining items.
46300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
46479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  // Wait for JNI_OnLoad in other thread.
465c604d731730b43231f63040c8db1d58304da0cf3Ian Rogers  ConditionVariable jni_on_load_cond_ GUARDED_BY(jni_on_load_lock_);
46679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  // Recursive invocation guard.
467f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_);
46879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  // Result of earlier JNI_OnLoad call.
469f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes  JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_);
47079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes};
47179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
47279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes// This exists mainly to keep implementation details out of the header file.
47379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughesclass Libraries {
47479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes public:
47579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  Libraries() {
47679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
47779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
47879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  ~Libraries() {
479c31664f3d82e6cd68275a529a8a73f067a52e8beElliott Hughes    STLDeleteValues(&libraries_);
48079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
48179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
482ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  void Dump(std::ostream& os) const {
483ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    bool first = true;
48402e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier    for (const auto& library : libraries_) {
485ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes      if (!first) {
486ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes        os << ' ';
487ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes      }
488ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes      first = false;
48902e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier      os << library.first;
490ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    }
491ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  }
492ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes
493ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  size_t size() const {
494ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    return libraries_.size();
495ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  }
496ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes
49779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  SharedLibrary* Get(const std::string& path) {
49802e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier    auto it = libraries_.find(path);
499e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return (it == libraries_.end()) ? nullptr : it->second;
50079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
50179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
50279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  void Put(const std::string& path, SharedLibrary* library) {
503a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes    libraries_.Put(path, library);
50479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
50579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
50679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  // See section 11.3 "Linking Native Methods" of the JNI spec.
507e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  void* FindNativeMethod(mirror::ArtMethod* m, std::string& detail)
508b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
50979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    std::string jni_short_name(JniShortName(m));
51079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    std::string jni_long_name(JniLongName(m));
511e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    const mirror::ClassLoader* declaring_class_loader = m->GetDeclaringClass()->GetClassLoader();
51202e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier    for (const auto& lib : libraries_) {
51302e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier      SharedLibrary* library = lib.second;
51479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      if (library->GetClassLoader() != declaring_class_loader) {
51579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes        // We only search libraries loaded by the appropriate ClassLoader.
51679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes        continue;
51779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      }
51879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      // Try the short name then the long name...
519355383f61d28f2dc8072fbde2639c80627adf16dYong WU      void* fn = nullptr;
520355383f61d28f2dc8072fbde2639c80627adf16dYong WU      if (UNLIKELY(library->NeedsNativeBridge())) {
521355383f61d28f2dc8072fbde2639c80627adf16dYong WU        fn = library->FindSymbolWithNativeBridge(jni_short_name, m);
522355383f61d28f2dc8072fbde2639c80627adf16dYong WU        if (fn == nullptr) {
523355383f61d28f2dc8072fbde2639c80627adf16dYong WU          fn = library->FindSymbolWithNativeBridge(jni_long_name, m);
524355383f61d28f2dc8072fbde2639c80627adf16dYong WU        }
525355383f61d28f2dc8072fbde2639c80627adf16dYong WU      } else {
526355383f61d28f2dc8072fbde2639c80627adf16dYong WU        fn = library->FindSymbol(jni_short_name);
527355383f61d28f2dc8072fbde2639c80627adf16dYong WU        if (fn == nullptr) {
528355383f61d28f2dc8072fbde2639c80627adf16dYong WU          fn = library->FindSymbol(jni_long_name);
529355383f61d28f2dc8072fbde2639c80627adf16dYong WU        }
53079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      }
531e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      if (fn != nullptr) {
5324dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes        VLOG(jni) << "[Found native code for " << PrettyMethod(m)
5334dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes                  << " in \"" << library->GetPath() << "\"]";
53479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes        return fn;
53579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      }
53679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    }
53779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    detail += "No implementation found for ";
538a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes    detail += PrettyMethod(m);
53992827a5fc2598589b3717269cc09c33b8c53f30bBrian Carlstrom    detail += " (tried " + jni_short_name + " and " + jni_long_name + ")";
54079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    LOG(ERROR) << detail;
541e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return nullptr;
54279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
54379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
54483c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier  void VisitRoots(RootCallback* callback, void* arg) {
5458f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier    for (auto& lib_pair : libraries_) {
54683c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier      lib_pair.second->VisitRoots(callback, arg);
5478f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier    }
5488f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier  }
5498f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier
55079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes private:
5515369c40f75fdcb1be7a7c06db212ce965c83a164Mathieu Chartier  AllocationTrackingSafeMap<std::string, SharedLibrary*, kAllocatorTagJNILibrarires> libraries_;
55279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes};
55379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
5542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers#define CHECK_NON_NULL_ARGUMENT(value) \
5552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
5563b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier
5572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers#define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
5582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
5592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
5602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers#define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
5612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
5622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
5632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers#define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
5642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
5652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
5662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers#define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
567e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (UNLIKELY(value == nullptr)) { \
5683b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    JniAbortF(name, #value " == null"); \
5692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return return_val; \
570bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  }
571bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
5723b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
573e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (UNLIKELY(length != 0 && value == nullptr)) { \
5743b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    JniAbortF(__FUNCTION__, #value " == null"); \
5752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return; \
5764ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers  }
5774ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers
578cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesclass JNI {
579cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes public:
58025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers  static jint GetVersion(JNIEnv*) {
581cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return JNI_VERSION_1_6;
582cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
583cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
58425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers  static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
585cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    LOG(WARNING) << "JNI DefineClass is not supported";
586e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return nullptr;
58718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
58818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
589cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jclass FindClass(JNIEnv* env, const char* name) {
5903b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(name);
5915fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    Runtime* runtime = Runtime::Current();
5925fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    ClassLinker* class_linker = runtime->GetClassLinker();
593cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    std::string descriptor(NormalizeJniClassDescriptor(name));
594ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedObjectAccess soa(env);
595e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = nullptr;
5965fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    if (runtime->IsStarted()) {
597eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      StackHandleScope<1> hs(soa.Self());
598eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
5999837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers      c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
6005fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    } else {
6019837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers      c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
6025fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    }
60300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jclass>(c);
604cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
605ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
60662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
6073b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(jlr_method);
60800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
60962f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    return soa.EncodeMethod(mirror::ArtMethod::FromReflectedMethod(soa, jlr_method));
61018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
61118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
61262f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
6133b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(jlr_field);
61400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
61562f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers    return soa.EncodeField(mirror::ArtField::FromReflectedField(soa, jlr_field));
616cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
61718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
618cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
6193b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
62000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
621e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ArtMethod* m = soa.DecodeMethod(mid);
622e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    CHECK(!kMovingMethods);
6238c41753e5eda8322b4d992fe88855058f4c0c2e1Mathieu Chartier    ScopedLocalRef<jobject> art_method(env, soa.AddLocalReference<jobject>(m));
624d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz    jobject reflect_method;
625d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz    if (m->IsConstructor()) {
626d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz      reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Constructor);
627d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz    } else {
628d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz      reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Method);
629d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz    }
630ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    if (env->ExceptionCheck()) {
631e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      return nullptr;
632ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    }
633e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    SetObjectField(env, reflect_method,
6348c41753e5eda8322b4d992fe88855058f4c0c2e1Mathieu Chartier                   WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod, art_method.get());
635ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    return reflect_method;
63618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
637ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
638cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
6393b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(fid);
64000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
641e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ArtField* f = soa.DecodeField(fid);
6428c41753e5eda8322b4d992fe88855058f4c0c2e1Mathieu Chartier    ScopedLocalRef<jobject> art_field(env, soa.AddLocalReference<jobject>(f));
643ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    jobject reflect_field = env->AllocObject(WellKnownClasses::java_lang_reflect_Field);
644ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    if (env->ExceptionCheck()) {
645e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      return nullptr;
646ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    }
647e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    SetObjectField(env, reflect_field,
6488c41753e5eda8322b4d992fe88855058f4c0c2e1Mathieu Chartier                   WellKnownClasses::java_lang_reflect_Field_artField, art_field.get());
649ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    return reflect_field;
650cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
651cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
65237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
6533b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_object);
65400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
655e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
65600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jclass>(o->GetClass());
65737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  }
65837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
659885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
6603b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
66100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
662e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
66300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jclass>(c->GetSuperClass());
66418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
66518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
6661268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // Note: java_class1 should be safely castable to java_class2, and
6671268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // not the other way around.
66837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
6692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
6702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
67100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
672e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
673e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
6741268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath    return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
675cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
67618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
677e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes  static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
6782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
679e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (jobj == nullptr) {
6805d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom      // Note: JNI is different from regular Java instanceof in this respect
68137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes      return JNI_TRUE;
68237f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    } else {
683ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom      ScopedObjectAccess soa(env);
684e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
685e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
686e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes      return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
68737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    }
68837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  }
68937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
69037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static jint Throw(JNIEnv* env, jthrowable java_exception) {
69100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
692e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
693e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (exception == nullptr) {
69437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes      return JNI_ERR;
69537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    }
69662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
69762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    soa.Self()->SetException(throw_location, exception);
69837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    return JNI_OK;
69937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  }
70037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
701e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes  static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
7022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
703e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return ThrowNewException(env, c, msg, nullptr);
70437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  }
70537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
70637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static jboolean ExceptionCheck(JNIEnv* env) {
707120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers    return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
70837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  }
70937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
71037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static void ExceptionClear(JNIEnv* env) {
711a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov    ScopedObjectAccess soa(env);
712a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov    soa.Self()->ClearException();
71318c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
71418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
71537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static void ExceptionDescribe(JNIEnv* env) {
71600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
71772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
7183a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov    // If we have no exception to describe, pass through.
7193a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov    if (!soa.Self()->GetException(nullptr)) {
7203a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov      return;
7213a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov    }
7223a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov
723eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    StackHandleScope<3> hs(soa.Self());
724eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    // TODO: Use nullptr instead of null handles?
725eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    auto old_throw_this_object(hs.NewHandle<mirror::Object>(nullptr));
726eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    auto old_throw_method(hs.NewHandle<mirror::ArtMethod>(nullptr));
727eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    auto old_exception(hs.NewHandle<mirror::Throwable>(nullptr));
72862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    uint32_t old_throw_dex_pc;
7299f1020305292a21fd14a402b189c765a125226abSebastien Hertz    bool old_is_exception_reported;
73062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    {
73162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      ThrowLocation old_throw_location;
732e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::Throwable* old_exception_obj = soa.Self()->GetException(&old_throw_location);
733eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      old_throw_this_object.Assign(old_throw_location.GetThis());
734eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      old_throw_method.Assign(old_throw_location.GetMethod());
735eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      old_exception.Assign(old_exception_obj);
73662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      old_throw_dex_pc = old_throw_location.GetDexPc();
7379f1020305292a21fd14a402b189c765a125226abSebastien Hertz      old_is_exception_reported = soa.Self()->IsExceptionReportedToInstrumentation();
73862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      soa.Self()->ClearException();
73962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    }
740491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom    ScopedLocalRef<jthrowable> exception(env,
741eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                                         soa.AddLocalReference<jthrowable>(old_exception.Get()));
74272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
74372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
744e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (mid == nullptr) {
74572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes      LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
746eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                   << PrettyTypeOf(old_exception.Get());
74772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    } else {
74872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes      env->CallVoidMethod(exception.get(), mid);
74962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      if (soa.Self()->IsExceptionPending()) {
750e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException(nullptr))
75172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                     << " thrown while calling printStackTrace";
75262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        soa.Self()->ClearException();
75372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes      }
75472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    }
755eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    ThrowLocation gc_safe_throw_location(old_throw_this_object.Get(), old_throw_method.Get(),
75662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                         old_throw_dex_pc);
75772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
758eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    soa.Self()->SetException(gc_safe_throw_location, old_exception.Get());
7599f1020305292a21fd14a402b189c765a125226abSebastien Hertz    soa.Self()->SetExceptionReportedToInstrumentation(old_is_exception_reported);
760cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
76118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
762cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jthrowable ExceptionOccurred(JNIEnv* env) {
76300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
764e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* exception = soa.Self()->GetException(nullptr);
76500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jthrowable>(exception);
76618c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
76718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
76825e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers  static void FatalError(JNIEnv*, const char* msg) {
769cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    LOG(FATAL) << "JNI FatalError called: " << msg;
770cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
77118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
7722ced6a534157d5d963693346904389c19775d2daElliott Hughes  static jint PushLocalFrame(JNIEnv* env, jint capacity) {
77335aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    // TODO: SOA may not be necessary but I do it to please lock annotations.
77435aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    ScopedObjectAccess soa(env);
77535aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    if (EnsureLocalCapacity(soa, capacity, "PushLocalFrame") != JNI_OK) {
7762ced6a534157d5d963693346904389c19775d2daElliott Hughes      return JNI_ERR;
7772ced6a534157d5d963693346904389c19775d2daElliott Hughes    }
778ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers    static_cast<JNIEnvExt*>(env)->PushFrame(capacity);
779cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return JNI_OK;
780c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes  }
781c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes
7822ced6a534157d5d963693346904389c19775d2daElliott Hughes  static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
78300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
784e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor);
78500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Env()->PopFrame();
78600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(survivor);
787cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
788c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes
7892ced6a534157d5d963693346904389c19775d2daElliott Hughes  static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
79035aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    // TODO: SOA may not be necessary but I do it to please lock annotations.
79135aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    ScopedObjectAccess soa(env);
79235aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    return EnsureLocalCapacity(soa, desired_capacity, "EnsureLocalCapacity");
79372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  }
79472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
795cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
79625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
797e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
798e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    // Check for null after decoding the object to handle cleared weak globals.
799e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    if (decoded_obj == nullptr) {
800e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier      return nullptr;
801e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    }
80200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JavaVMExt* vm = soa.Vm();
803cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    IndirectReferenceTable& globals = vm->globals;
804b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers    WriterMutexLock mu(soa.Self(), vm->globals_lock);
80500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj);
806cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return reinterpret_cast<jobject>(ref);
807c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes  }
808ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
809cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
810e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (obj == nullptr) {
811cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      return;
812cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
813ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers    JavaVMExt* vm = reinterpret_cast<JNIEnvExt*>(env)->vm;
814cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    IndirectReferenceTable& globals = vm->globals;
815ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers    Thread* self = reinterpret_cast<JNIEnvExt*>(env)->self;
816b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers    WriterMutexLock mu(self, vm->globals_lock);
817ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
818cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
819cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
820cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                   << "failed to find entry";
821cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
822cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
823ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
824cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
82500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
826e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return AddWeakGlobalReference(soa, soa.Decode<mirror::Object*>(obj));
827cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
828ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
829cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
830c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    if (obj != nullptr) {
831c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier      ScopedObjectAccess soa(env);
832c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier      soa.Vm()->DeleteWeakGlobalRef(soa.Self(), obj);
833cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
834cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
835ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
836cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jobject NewLocalRef(JNIEnv* env, jobject obj) {
83725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
838e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
839e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    // Check for null after decoding the object to handle cleared weak globals.
840e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    if (decoded_obj == nullptr) {
841e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier      return nullptr;
842e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    }
843e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    return soa.AddLocalReference<jobject>(decoded_obj);
8444dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
845ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
846cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static void DeleteLocalRef(JNIEnv* env, jobject obj) {
847e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (obj == nullptr) {
848cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      return;
849cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
85035aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    ScopedObjectAccess soa(env);
851ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers    IndirectReferenceTable& locals = reinterpret_cast<JNIEnvExt*>(env)->locals;
852cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
853ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers    uint32_t cookie = reinterpret_cast<JNIEnvExt*>(env)->local_ref_cookie;
854cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    if (!locals.Remove(cookie, obj)) {
855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // Attempting to delete a local reference that is not in the
856cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // topmost local reference frame is a no-op.  DeleteLocalRef returns
857cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // void and doesn't throw any exceptions, but we should probably
858cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // complain about it so the user will notice that things aren't
859cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // going quite the way they expect.
860cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
861cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                   << "failed to find entry";
862cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
86383ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro  }
864cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
865cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
866ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    if (obj1 == obj2) {
867ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom      return JNI_TRUE;
868ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    } else {
869ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom      ScopedObjectAccess soa(env);
870491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom      return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
871491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom              ? JNI_TRUE : JNI_FALSE;
872ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    }
87383ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro  }
874cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
875885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jobject AllocObject(JNIEnv* env, jclass java_class) {
8763b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
87700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
878e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
879c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    if (c == nullptr) {
880c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      return nullptr;
881885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    }
88250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
883cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
884cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
885bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
886cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list args;
88772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(args, mid);
8883b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
8893b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
890bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    jobject result = NewObjectV(env, java_class, mid, args);
891cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(args);
892cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return result;
893cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
894cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
89572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
8963b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
8973b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
89800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
899e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
900c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    if (c == nullptr) {
901c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      return nullptr;
902885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    }
903e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* result = c->AllocObject(soa.Self());
904c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    if (result == nullptr) {
905c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      return nullptr;
90630646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes    }
90700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject local_result = soa.AddLocalReference<jobject>(result);
90872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
909e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (soa.Self()->IsExceptionPending()) {
910c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      return nullptr;
9115d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers    }
912e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return local_result;
913cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
914cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
91572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
9163b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
9173b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
91800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
919e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
920c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    if (c == nullptr) {
921c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      return nullptr;
922885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    }
923e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* result = c->AllocObject(soa.Self());
924e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (result == nullptr) {
925e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      return nullptr;
92630646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes    }
92700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject local_result = soa.AddLocalReference<jobjectArray>(result);
92872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
929e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (soa.Self()->IsExceptionPending()) {
930e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      return nullptr;
9315d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers    }
932e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return local_result;
933cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
934cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
935bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
9363b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
9373b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(name);
9383b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(sig);
93900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
940bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    return FindMethodID(soa, java_class, name, sig, false);
941cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
942ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
943bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
944bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                     const char* sig) {
9453b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
9463b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(name);
9473b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(sig);
94800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
949bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    return FindMethodID(soa, java_class, name, sig, true);
950cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
951ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
95272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
95372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
95472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
9553b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
9563b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
95725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
95800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
95972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
96000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
961cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
962ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
96372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
9643b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
9653b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
96600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
96700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
96800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
969cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
970ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
97172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
9723b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
9733b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
97400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
97553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    JValue result(InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
97653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                                                      args));
97700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
978cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
979ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
98072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
98172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
98272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
9832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
9842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
98525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
98600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
98772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
988f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetZ();
989cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
990ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
99172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
9922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
9932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
99400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
99500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
996cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
997ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
99872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
9992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
100100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
100253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
100353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                                               args).GetZ();
1004cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1005ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
100672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
100772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
100872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
10092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1011bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    ScopedObjectAccess soa(env);
101200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
101372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
1014f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetB();
1015cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1016ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
101772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
10182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
102000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
102100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
1022cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1023ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
102472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
10252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
102700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
102853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
102953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                                               args).GetB();
1030cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1031ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
103272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
103372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
103472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
10352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
103725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
103800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
103972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
1040f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetC();
1041cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1042ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
104372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
10442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
104600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
104700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
1048cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1049ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
105072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
10512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
105300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
105453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
105553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                                               args).GetC();
1056cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1057ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
105872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
105972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
106072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
10612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
106325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
106400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
106572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
1066f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetD();
1067cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1068ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
106972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
10702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
107200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
107300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
1074cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1075ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
107672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
10772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
107900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
108053b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
108153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                                               args).GetD();
1082cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1083ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
108472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
108572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
108672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
10872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1089bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    ScopedObjectAccess soa(env);
109000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
109172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
1092f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetF();
1093cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1094ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
109572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
10962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
109800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
109900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
1100cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1101ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
110272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
11032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
110500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
110653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
110753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                                               args).GetF();
1108cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1109ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
111072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
111172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
111272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
11132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
111525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
111600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
111772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
1118f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetI();
1119cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1120ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
112172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
11222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
112400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
112500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
1126cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1127ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
112872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
11292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
113100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
113253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
113353b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                                               args).GetI();
1134cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1135ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
113672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
113772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
113872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
11392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
114125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
114200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
114372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
1144f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetJ();
1145cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1146ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
114772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
11482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
115000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
115100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
1152cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1153ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
115472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
11552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
115700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
115853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
115953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                                               args).GetJ();
1160cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1161ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
116272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
116372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
116472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
11652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
116725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
116800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
116972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
1170f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetS();
1171cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1172ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
117372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
11742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
117600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
117700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
1178cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1179ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
118072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
11812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
118300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
118453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
118553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers                                               args).GetS();
1186cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1187ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
118872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
118972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
119072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
11912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
11922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
119325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
11941b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers    InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
119572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
1196cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1197ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
119872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
11992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
12002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
120100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
120200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
1203cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1204ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
120572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
12062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
12072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
120800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
120953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args);
1210cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1211ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
12121bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1213cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
121472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
12153b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
12163b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
121725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
121800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
121900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1220cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1221cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return local_result;
1222cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1223ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1224bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1225bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                             va_list args) {
12263b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
12273b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
122800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
122900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, args));
123000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
1231cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1232ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1233bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1234bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                             jvalue* args) {
12353b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
12363b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
123700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
123853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    JValue result(InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args));
123900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
1240cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1241ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1242bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1243bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                              ...) {
1244cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
124572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
12462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
12472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
124825e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
124900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1250cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1251f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetZ();
1252cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1253ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1254bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1255bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                               va_list args) {
12562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
12572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
125800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
125900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
1260cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1261ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1262bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1263bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                               jvalue* args) {
12642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
12652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
126600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
126753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetZ();
1268cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1269ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
12701bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1271cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
127272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
12732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
12742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
127525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
127600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1277cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1278f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetB();
1279cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1280ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1281bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1282bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         va_list args) {
12832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
12842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
128500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
128600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetB();
1287cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1288ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1289bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1290bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         jvalue* args) {
12912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
12922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
129300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
129453b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetB();
1295cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1296ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
12971bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1298cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
129972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
13002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
13012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1302bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    ScopedObjectAccess soa(env);
130300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1304cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1305f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetC();
1306cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1307ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1308bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1309bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         va_list args) {
13102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
13112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
131200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
131300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetC();
1314cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1315ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1316bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1317bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         jvalue* args) {
13182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
13192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
132000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
132153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetC();
1322cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1323ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
13241bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1325cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
132672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
13272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
13282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
132925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
133000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1331cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1332f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetS();
1333cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1334ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1335bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1336bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                           va_list args) {
13372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
13382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
133900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
134000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetS();
1341cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1342ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1343bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1344bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                           jvalue* args) {
13452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
13462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
134700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
134853b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetS();
1349cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1350ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
13511bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1352cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
135372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
13542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
13552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
135625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
135700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1358cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1359f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetI();
1360cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1361ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1362bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1363bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                       va_list args) {
13642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
13652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
136600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
136700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetI();
1368cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1369ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1370bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1371bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                       jvalue* args) {
13722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
13732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
137400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
137553b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetI();
1376cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1377ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
13781bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1379cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
138072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
13812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
13822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
138325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
138400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1385cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1386f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetJ();
1387cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1388ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1389bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1390bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         va_list args) {
13912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
13922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
139300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
139400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
1395cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1396ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1397bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1398bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         jvalue* args) {
13992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
14002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
140100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
140253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetJ();
1403cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1404ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14051bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1406cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
140772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
14082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
14092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
141025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
141100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1412cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1413f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetF();
1414cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1415ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1416bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1417bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                           va_list args) {
14182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
14192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
142000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
142100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetF();
1422cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1423ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1424bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1425bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                           jvalue* args) {
14262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
14272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
142800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
142953b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetF();
1430cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1431ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14321bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1433cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
143472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
14352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
14362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
143725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
143800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1439cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1440f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetD();
1441cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1442ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1443bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1444bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                             va_list args) {
14452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
14462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
144700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
144800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetD();
1449cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1450ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1451bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1452bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                             jvalue* args) {
14532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
14542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
145500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
145653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetD();
1457cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1458ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14591bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1460cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
146172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
14622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
14632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
146425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
146500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    InvokeWithVarArgs(soa, obj, mid, ap);
1466cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1467cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1468ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1469ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1470ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                        va_list args) {
14712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
14722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
147300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
147400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    InvokeWithVarArgs(soa, obj, mid, args);
1475cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1476ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1477bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1478bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                        jvalue* args) {
14792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
14802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
148100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
148253b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers    InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args);
1483cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1484ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1485bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
14863b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
14873b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(name);
14883b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(sig);
148900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1490bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    return FindFieldID(soa, java_class, name, sig, false);
1491cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1492ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1493bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1494bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                   const char* sig) {
14953b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
14963b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(name);
14973b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(sig);
149800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1499bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    return FindFieldID(soa, java_class, name, sig, true);
1500cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1501ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1502885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
15033b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
15043b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(fid);
150500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1506e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* o = soa.Decode<mirror::Object*>(obj);
1507e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ArtField* f = soa.DecodeField(fid);
150800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(f->GetObject(o));
1509cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1510ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1511885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
15123b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(fid);
151300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1514e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ArtField* f = soa.DecodeField(fid);
15152fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
1516cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1517ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1518885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
15192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
15202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
152100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1522e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1523e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1524e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ArtField* f = soa.DecodeField(fid);
1525d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetObject<false>(o, v);
1526cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1527ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1528885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
15292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
153000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1531e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1532e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ArtField* f = soa.DecodeField(fid);
1533d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetObject<false>(f->GetDeclaringClass(), v);
1534cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1535ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1536885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes#define GET_PRIMITIVE_FIELD(fn, instance) \
15372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
15382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
153900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env); \
1540e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1541e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::ArtField* f = soa.DecodeField(fid); \
1542bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  return f->Get ##fn (o)
1543885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
15442fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#define GET_STATIC_PRIMITIVE_FIELD(fn) \
15452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
15462fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  ScopedObjectAccess soa(env); \
1547e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::ArtField* f = soa.DecodeField(fid); \
1548bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  return f->Get ##fn (f->GetDeclaringClass())
15492fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers
1550885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes#define SET_PRIMITIVE_FIELD(fn, instance, value) \
15512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
15522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
155300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env); \
1554e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1555e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::ArtField* f = soa.DecodeField(fid); \
1556d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  f->Set ##fn <false>(o, value)
1557885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
15582fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
15592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
15602fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  ScopedObjectAccess soa(env); \
1561e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::ArtField* f = soa.DecodeField(fid); \
1562d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  f->Set ##fn <false>(f->GetDeclaringClass(), value)
15632fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers
1564885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
1565bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Boolean, obj);
1566cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1567ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1568885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
1569bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Byte, obj);
1570cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1571ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1572885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
1573bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Char, obj);
1574cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1575ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1576885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
1577bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Short, obj);
1578cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1579ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1580885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
1581bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Int, obj);
1582cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1583ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1584885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
1585bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Long, obj);
1586cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1587ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1588885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
1589bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Float, obj);
1590cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1591ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1592885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
1593bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Double, obj);
1594cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1595ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15961bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
1597bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Boolean);
1598cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1599ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
16001bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
1601bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Byte);
160283ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro  }
1603cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
16041bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
1605bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Char);
16069b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  }
1607ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
16081bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
1609bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Short);
1610cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1611ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
16121bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
1613bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Int);
1614cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1615ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
16161bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
1617bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Long);
1618885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1619885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
16201bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
1621bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Float);
1622885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1623885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
16241bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
1625bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Double);
1626885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1627885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1628885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
1629bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Boolean, obj, v);
1630885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1631885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1632885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
1633bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Byte, obj, v);
1634885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1635885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1636885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
1637bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Char, obj, v);
1638885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1639885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1640885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
1641bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Float, obj, v);
1642885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1643885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1644885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
1645bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Double, obj, v);
1646885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1647885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1648885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
1649bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Int, obj, v);
1650885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1651885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1652885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
1653bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Long, obj, v);
1654885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1655885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1656885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
1657bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Short, obj, v);
1658885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1659885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1660885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
1661bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
1662885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1663885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1664885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
1665bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Byte, v);
1666885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1667885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1668885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
1669bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Char, v);
1670885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1671885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1672885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
1673bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Float, v);
1674885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1675885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1676885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
1677bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Double, v);
1678885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1679885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1680885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
1681bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Int, v);
1682885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1683885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1684885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
1685bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Long, v);
1686885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1687885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1688885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
1689bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Short, v);
1690cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1691ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
16921bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1693cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
169472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
16953b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
169625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1697e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
169800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1699cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1700cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return local_result;
1701cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1702ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17031bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
17043b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
170500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1706e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
170700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
1708cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1709ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17101bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
17113b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
171200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1713e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithJValues(soa, nullptr, mid, args));
171400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
1715cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1716ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17171bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1718cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
171972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
17202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
172125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1722e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1723cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1724f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetZ();
1725cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1726ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17271bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
17282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
172900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1730e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
1731cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1732ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17331bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
17342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
173500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1736e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
1737cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1738ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17391bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1740cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
174172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
17422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
174325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1744e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1745cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1746f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetB();
1747cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1748ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17491bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
17502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
175100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1752e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
1753cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1754ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17551bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
17562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
175700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1758e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetB();
1759cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1760ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17611bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1762cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
176372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
17642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
176525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1766e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1767cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1768f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetC();
1769cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1770ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17711bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
17722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
177300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1774e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
1775cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1776ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17771bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
17782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
177900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1780e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetC();
1781cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1782ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17831bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1784cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
178572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
17862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
178725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1788e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1789cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1790f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetS();
1791cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1792ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17931bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
17942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
179500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1796e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
1797cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1798ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17991bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
18002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
180100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1802e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetS();
1803cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1804ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18051bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1806cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
180772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
18082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
180925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1810e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1811cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1812f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetI();
1813cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1814ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18151bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
18162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
181700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1818e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
1819cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1820ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18211bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
18222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
182300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1824e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetI();
1825cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1826ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18271bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1828cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
182972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
18302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
183125e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1832e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1833cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1834f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetJ();
1835cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1836ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18371bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
18382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
183900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1840e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
1841cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1842ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18431bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
18442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
184500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1846e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
1847cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1848ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18491bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1850cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
185172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
18522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
185325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1854e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1856f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetF();
1857cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1858ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18591bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
18602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
186100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1862e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
1863cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1864ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18651bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
18662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
186700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1868e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetF();
1869cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1870ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18711bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1872cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
187372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
18742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
187525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1876e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1877cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1878f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetD();
1879cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1880ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18811bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
18822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
188300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1884e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
1885cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1886ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18871bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
18882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
188900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1890e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetD();
1891cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1892ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
18931bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1894cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
189572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
18962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
189725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1898e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    InvokeWithVarArgs(soa, nullptr, mid, ap);
1899cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1900cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1901ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
19021bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
19032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
190400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1905e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    InvokeWithVarArgs(soa, nullptr, mid, args);
1906cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1907ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
19081bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
19092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
191000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1911e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    InvokeWithJValues(soa, nullptr, mid, args);
1912cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1913ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1914814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
19151d99e4549309d05007d041d058b1878de88e9585Ian Rogers    if (UNLIKELY(char_count < 0)) {
19161d99e4549309d05007d041d058b1878de88e9585Ian Rogers      JniAbortF("NewString", "char_count < 0: %d", char_count);
19171d99e4549309d05007d041d058b1878de88e9585Ian Rogers      return nullptr;
19181d99e4549309d05007d041d058b1878de88e9585Ian Rogers    }
19191d99e4549309d05007d041d058b1878de88e9585Ian Rogers    if (UNLIKELY(chars == nullptr && char_count > 0)) {
19201d99e4549309d05007d041d058b1878de88e9585Ian Rogers      JniAbortF("NewString", "chars == null && char_count > 0");
19211d99e4549309d05007d041d058b1878de88e9585Ian Rogers      return nullptr;
1922bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    }
192300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1924e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
192500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jstring>(result);
1926cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1927ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1928814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  static jstring NewStringUTF(JNIEnv* env, const char* utf) {
1929e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (utf == nullptr) {
1930e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      return nullptr;
1931814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes    }
193200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1933e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
193400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jstring>(result);
1935cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1936ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1937814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  static jsize GetStringLength(JNIEnv* env, jstring java_string) {
19382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
193900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1940e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return soa.Decode<mirror::String*>(java_string)->GetLength();
1941814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  }
1942814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1943814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
19442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
194500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1946e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
1947814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  }
1948814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1949bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1950bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                              jchar* buf) {
19512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
195200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1953e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* s = soa.Decode<mirror::String*>(java_string);
1954b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    if (start < 0 || length < 0 || start + length > s->GetLength()) {
195500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      ThrowSIOOBE(soa, start, length, s->GetLength());
1956b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    } else {
19573b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier      CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1958b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
1959b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      memcpy(buf, chars + start, length * sizeof(jchar));
1960b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    }
19618a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes  }
1962ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1963bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1964bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 char* buf) {
19652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
196600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1967e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* s = soa.Decode<mirror::String*>(java_string);
1968b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    if (start < 0 || length < 0 || start + length > s->GetLength()) {
196900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      ThrowSIOOBE(soa, start, length, s->GetLength());
1970b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    } else {
19713b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier      CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1972b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
1973b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      ConvertUtf16ToModifiedUtf8(buf, chars + start, length);
1974b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    }
1975cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1976ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
19777577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
19783b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_string);
197900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1980e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* s = soa.Decode<mirror::String*>(java_string);
1981e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::CharArray* chars = s->GetCharArray();
198256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    gc::Heap* heap = Runtime::Current()->GetHeap();
198356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    if (heap->IsMovableObject(chars)) {
198456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      if (is_copy != nullptr) {
198556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        *is_copy = JNI_TRUE;
198656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      }
198756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      int32_t char_count = s->GetLength();
198856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      int32_t offset = s->GetOffset();
198956890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      jchar* bytes = new jchar[char_count];
199056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      for (int32_t i = 0; i < char_count; i++) {
199156890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        bytes[i] = chars->Get(i + offset);
199256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      }
199356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      return bytes;
199456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    } else {
199556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      if (is_copy != nullptr) {
199656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        *is_copy = JNI_FALSE;
199756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      }
199856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      return static_cast<jchar*>(chars->GetData() + s->GetOffset());
19997577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    }
2000cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2001ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2002590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
20032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
200400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
200556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    mirror::String* s = soa.Decode<mirror::String*>(java_string);
200656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    mirror::CharArray* s_chars = s->GetCharArray();
200756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    if (chars != (s_chars->GetData() + s->GetOffset())) {
200856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      delete[] chars;
200956890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    }
2010cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2011ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
20127577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
201356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    CHECK_NON_NULL_ARGUMENT(java_string);
201456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    ScopedObjectAccess soa(env);
201556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    mirror::String* s = soa.Decode<mirror::String*>(java_string);
201656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    mirror::CharArray* chars = s->GetCharArray();
201756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    int32_t offset = s->GetOffset();
201856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    gc::Heap* heap = Runtime::Current()->GetHeap();
201956890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    if (heap->IsMovableObject(chars)) {
202056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      StackHandleScope<1> hs(soa.Self());
202156890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      HandleWrapper<mirror::CharArray> h(hs.NewHandleWrapper(&chars));
202256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      heap->IncrementDisableMovingGC(soa.Self());
202356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    }
202456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    if (is_copy != nullptr) {
202556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      *is_copy = JNI_FALSE;
202656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    }
202756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    return static_cast<jchar*>(chars->GetData() + offset);
2028cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2029ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
20307577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) {
203156890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
203256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    ScopedObjectAccess soa(env);
203356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    gc::Heap* heap = Runtime::Current()->GetHeap();
203456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    mirror::String* s = soa.Decode<mirror::String*>(java_string);
203556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    mirror::CharArray* s_chars = s->GetCharArray();
203656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    if (heap->IsMovableObject(s_chars)) {
203756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      heap->DecrementDisableMovingGC(soa.Self());
203856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    }
2039cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2040ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
20417577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
2042e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (java_string == nullptr) {
2043e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      return nullptr;
20447577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    }
2045e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (is_copy != nullptr) {
20467577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes      *is_copy = JNI_TRUE;
20477577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    }
2048ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers    ScopedObjectAccess soa(env);
2049e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* s = soa.Decode<mirror::String*>(java_string);
20507577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    size_t byte_count = s->GetUtfLength();
20517577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    char* bytes = new char[byte_count + 1];
2052e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    CHECK(bytes != nullptr);  // bionic aborts anyway.
20537577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    const uint16_t* chars = s->GetCharArray()->GetData() + s->GetOffset();
20547577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength());
20557577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    bytes[byte_count] = '\0';
20567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    return bytes;
2057b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  }
2058b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
20597577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static void ReleaseStringUTFChars(JNIEnv* env, jstring, const char* chars) {
20607577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    delete[] chars;
2061b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  }
2062b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
2063bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
20642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
206500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2066e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
2067ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    if (UNLIKELY(!obj->IsArrayInstance())) {
206896a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes      JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
206996a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    }
2070e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Array* array = obj->AsArray();
2071bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes    return array->GetLength();
2072cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2073ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2074814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
20753b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_array);
207600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2077e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ObjectArray<mirror::Object>* array =
2078e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
207900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(array->Get(index));
2080cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2081d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
2082bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
2083bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                    jobject java_value) {
20842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
208500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2086e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ObjectArray<mirror::Object>* array =
2087e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
2088e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
2089d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    array->Set<false>(index, value);
2090cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2091f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
2092cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
20932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
2094cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2095ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2096cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
20972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
2098cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2099ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2100cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jcharArray NewCharArray(JNIEnv* env, jsize length) {
21012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
2102cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2103ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2104cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
21052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
2106cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2107ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2108cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
21092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
2110cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2111ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2112cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jintArray NewIntArray(JNIEnv* env, jsize length) {
21132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
2114cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2115ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2116cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jlongArray NewLongArray(JNIEnv* env, jsize length) {
21172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
2118cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2119f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
21201d99e4549309d05007d041d058b1878de88e9585Ian Rogers  static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
21211d99e4549309d05007d041d058b1878de88e9585Ian Rogers                                     jobject initial_element) {
21221d99e4549309d05007d041d058b1878de88e9585Ian Rogers    if (UNLIKELY(length < 0)) {
212396a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes      JniAbortF("NewObjectArray", "negative array length: %d", length);
21241d99e4549309d05007d041d058b1878de88e9585Ian Rogers      return nullptr;
212596a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    }
21262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT(element_jclass);
2127cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
2128cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    // Compute the array class corresponding to the given element class.
2129ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedObjectAccess soa(env);
2130e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* array_class;
21311d99e4549309d05007d041d058b1878de88e9585Ian Rogers    {
2132e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
21331d99e4549309d05007d041d058b1878de88e9585Ian Rogers      if (UNLIKELY(element_class->IsPrimitive())) {
21341d99e4549309d05007d041d058b1878de88e9585Ian Rogers        JniAbortF("NewObjectArray", "not an object type: %s",
21351d99e4549309d05007d041d058b1878de88e9585Ian Rogers                  PrettyDescriptor(element_class).c_str());
21361d99e4549309d05007d041d058b1878de88e9585Ian Rogers        return nullptr;
21371d99e4549309d05007d041d058b1878de88e9585Ian Rogers      }
21381d99e4549309d05007d041d058b1878de88e9585Ian Rogers      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2139b74cd29802f364b4cec88f4913fa38ade26b8fabMathieu Chartier      array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
21401d99e4549309d05007d041d058b1878de88e9585Ian Rogers      if (UNLIKELY(array_class == nullptr)) {
21411d99e4549309d05007d041d058b1878de88e9585Ian Rogers        return nullptr;
21421d99e4549309d05007d041d058b1878de88e9585Ian Rogers      }
2143cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
2144cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
21457577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    // Allocate and initialize if necessary.
2146e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ObjectArray<mirror::Object>* result =
2147e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
21481d99e4549309d05007d041d058b1878de88e9585Ian Rogers    if (result != nullptr && initial_element != nullptr) {
2149e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
21501d99e4549309d05007d041d058b1878de88e9585Ian Rogers      if (initial_object != nullptr) {
21511d99e4549309d05007d041d058b1878de88e9585Ian Rogers        mirror::Class* element_class = result->GetClass()->GetComponentType();
21521d99e4549309d05007d041d058b1878de88e9585Ian Rogers        if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
21531d99e4549309d05007d041d058b1878de88e9585Ian Rogers          JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with element "
21541d99e4549309d05007d041d058b1878de88e9585Ian Rogers                    "type of '%s'", PrettyDescriptor(initial_object->GetClass()).c_str(),
21551d99e4549309d05007d041d058b1878de88e9585Ian Rogers                    PrettyDescriptor(element_class).c_str());
21561d99e4549309d05007d041d058b1878de88e9585Ian Rogers
21571d99e4549309d05007d041d058b1878de88e9585Ian Rogers        } else {
21581d99e4549309d05007d041d058b1878de88e9585Ian Rogers          for (jsize i = 0; i < length; ++i) {
2159d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz            result->SetWithoutChecks<false>(i, initial_object);
21601d99e4549309d05007d041d058b1878de88e9585Ian Rogers          }
21611d99e4549309d05007d041d058b1878de88e9585Ian Rogers        }
21627577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes      }
21637577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    }
216400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobjectArray>(result);
2165f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes  }
2166f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
2167cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jshortArray NewShortArray(JNIEnv* env, jsize length) {
21682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
2169cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2170ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2171a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers  static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
21723b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_array);
217300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2174e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
21752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
21762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
21772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                PrettyDescriptor(array->GetClass()).c_str());
21782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return nullptr;
21792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
2180590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    gc::Heap* heap = Runtime::Current()->GetHeap();
2181590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    if (heap->IsMovableObject(array)) {
21821d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier      heap->IncrementDisableMovingGC(soa.Self());
2183590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
2184e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      array = soa.Decode<mirror::Array*>(java_array);
2185590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    }
2186590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    if (is_copy != nullptr) {
2187a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers      *is_copy = JNI_FALSE;
2188a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers    }
2189ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
2190b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  }
2191b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
21922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
21932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                            jint mode) {
21942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
21952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ScopedObjectAccess soa(env);
21962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
21972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
21982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
21992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                PrettyDescriptor(array->GetClass()).c_str());
22002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return;
22012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
22022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    const size_t component_size = array->GetClass()->GetComponentSize();
22032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray(soa, array, component_size, elements, mode);
2204b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  }
2205b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
22067577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
22072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
2208cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2209ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
22107577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
22112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
2212cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2213ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
22147577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
22152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
2216cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2217ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
22187577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
22192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
2220cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2221ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
22227577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
22232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
2224cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2225ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
22267577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
22272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
2228cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2229ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
22307577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
22312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
2232cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2233ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
22347577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
22352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
2236cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2237ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2238590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2239590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                                          jint mode) {
22402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
22412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                                         mode);
2242cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2243ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2244590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
22452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
2246cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2247ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2248590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
22492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
2250cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2251ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2252590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2253590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                                         jint mode) {
22542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
2255cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2256ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2257590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2258590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                                        jint mode) {
22592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
2260cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2261ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2262590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
22632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
2264cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2265ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2266590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
22672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
2268cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2269ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2270590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2271590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                                        jint mode) {
22722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
2273cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2274ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2275bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2276bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                    jboolean* buf) {
22772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
2278e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                                                           length, buf);
2279cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2280ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2281bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2282bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 jbyte* buf) {
22832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
2284cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2285ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2286bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2287bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 jchar* buf) {
22882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2289cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2290ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2291bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2292bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                   jdouble* buf) {
22932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2294e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                                                        buf);
2295cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2296ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2297bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2298bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                  jfloat* buf) {
22992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2300e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                                                     buf);
2301cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2302ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2303bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2304bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                jint* buf) {
23052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2306cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2307ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2308bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2309bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 jlong* buf) {
23102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2311cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2312ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2313bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2314bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                  jshort* buf) {
23152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2316e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                                                     buf);
2317cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2318ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2319bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2320bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                    const jboolean* buf) {
23212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
2322491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                                                                           length, buf);
2323cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2324ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2325bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2326bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 const jbyte* buf) {
23272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
2328cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2329ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2330bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2331bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 const jchar* buf) {
23322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2333cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2334ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2335bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2336bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                   const jdouble* buf) {
23372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2338491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                                                                        buf);
2339cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2340ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2341bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2342bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                  const jfloat* buf) {
23432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2344491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                                                                     buf);
2345cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2346ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2347bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2348bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                const jint* buf) {
23492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2350cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2351ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2352bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2353bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 const jlong* buf) {
23542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2355cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2356ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2357bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2358bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                  const jshort* buf) {
23592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2360e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                                                     buf);
2361cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2362ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2363bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2364bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                              jint method_count) {
2365c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes    return RegisterNativeMethods(env, java_class, methods, method_count, true);
2366c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes  }
2367c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes
2368bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2369bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                    jint method_count, bool return_errors) {
2370bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    if (UNLIKELY(method_count < 0)) {
2371aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes      JniAbortF("RegisterNatives", "negative method count: %d", method_count);
2372bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers      return JNI_ERR;  // Not reached.
2373bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    }
23742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
237500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2376e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
2377bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    if (UNLIKELY(method_count == 0)) {
2378bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers      LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2379bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers          << PrettyDescriptor(c);
2380bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers      return JNI_OK;
2381bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    }
23822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
2383bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    for (jint i = 0; i < method_count; ++i) {
2384cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      const char* name = methods[i].name;
2385cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      const char* sig = methods[i].signature;
2386fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      const void* fnPtr = methods[i].fnPtr;
2387fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      if (UNLIKELY(name == nullptr)) {
2388fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2389fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        return JNI_ERR;
2390fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      } else if (UNLIKELY(sig == nullptr)) {
2391fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2392fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        return JNI_ERR;
2393fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      } else if (UNLIKELY(fnPtr == nullptr)) {
2394fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2395fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        return JNI_ERR;
2396fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      }
23971eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers      bool is_fast = false;
2398cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      if (*sig == '!') {
23991eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers        is_fast = true;
2400cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        ++sig;
2401cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      }
24020af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
2403e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::ArtMethod* m = c->FindDirectMethod(name, sig);
2404e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      if (m == nullptr) {
24055174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes        m = c->FindVirtualMethod(name, sig);
2406cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      }
2407e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      if (m == nullptr) {
24080177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers        c->DumpClass(LOG(ERROR), mirror::Class::kDumpClassFullDetail);
2409c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes        LOG(return_errors ? ERROR : FATAL) << "Failed to register native method "
24100177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers            << PrettyDescriptor(c) << "." << name << sig << " in "
24110177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers            << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
241200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
2413cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        return JNI_ERR;
24145174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes      } else if (!m->IsNative()) {
2415c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes        LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
2416bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            << PrettyDescriptor(c) << "." << name << sig
2417bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            << " as native";
241800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        ThrowNoSuchMethodError(soa, c, name, sig, "native");
2419cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        return JNI_ERR;
2420cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      }
24215174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
24224dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes      VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
24235174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
2424fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      m->RegisterNative(soa.Self(), fnPtr, is_fast);
24254dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers    }
2426cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return JNI_OK;
24274dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
2428ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
24295174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes  static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
24302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
243100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2432e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
24335174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
24344dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
24355174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
24362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    size_t unregistered_count = 0;
24375174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
2438e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::ArtMethod* m = c->GetDirectMethod(i);
24395174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes      if (m->IsNative()) {
244000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        m->UnregisterNative(soa.Self());
24412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        unregistered_count++;
24425174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes      }
24435174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    }
24445174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
2445e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::ArtMethod* m = c->GetVirtualMethod(i);
24465174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes      if (m->IsNative()) {
244700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        m->UnregisterNative(soa.Self());
24482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        unregistered_count++;
24495174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes      }
24505174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    }
24515174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
24522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (unregistered_count == 0) {
24532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
24542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers          << PrettyDescriptor(c) << "' that contains no native methods";
24552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
24565174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    return JNI_OK;
2457cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2458ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2459719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers  static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
24602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
246100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2462e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2463e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    o = o->MonitorEnter(soa.Self());
246400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (soa.Self()->IsExceptionPending()) {
2465ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes      return JNI_ERR;
2466ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes    }
246700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Env()->monitors.Add(o);
2468ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes    return JNI_OK;
2469cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2470ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2471719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers  static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
24722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
247300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2474e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
247500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    o->MonitorExit(soa.Self());
247600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (soa.Self()->IsExceptionPending()) {
2477ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes      return JNI_ERR;
2478ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes    }
247900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Env()->monitors.Remove(o);
2480ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes    return JNI_OK;
2481f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes  }
2482ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2483cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
24842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
2485cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    Runtime* runtime = Runtime::Current();
2486e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (runtime != nullptr) {
248769f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes      *vm = runtime->GetJavaVM();
2488cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    } else {
2489e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      *vm = nullptr;
2490cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
2491e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return (*vm != nullptr) ? JNI_OK : JNI_ERR;
2492cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2493ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2494b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
249596a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    if (capacity < 0) {
2496ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64, capacity);
249745d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom      return nullptr;
249896a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    }
2499e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (address == nullptr && capacity != 0) {
2500e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      JniAbortF("NewDirectByteBuffer", "non-zero capacity for nullptr pointer: %" PRId64, capacity);
250145d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom      return nullptr;
250296a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    }
2503ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
250485a93364e5111dc56a73eed0130856e66cab0802Brian Carlstrom    // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
250545d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    if (capacity > INT_MAX) {
250645d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom      JniAbortF("NewDirectByteBuffer", "buffer capacity greater than maximum jint: %" PRId64, capacity);
250745d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom      return nullptr;
250845d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    }
2509b56812165dd3a2e6eb8b85c810943b3d7bd9bfc4Elliott Hughes    jlong address_arg = reinterpret_cast<jlong>(address);
2510b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    jint capacity_arg = static_cast<jint>(capacity);
2511ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2512aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes    jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2513aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes                                    WellKnownClasses::java_nio_DirectByteBuffer_init,
2514eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes                                    address_arg, capacity_arg);
2515e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
2516cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2517ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2518b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
2519e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return reinterpret_cast<void*>(env->GetLongField(
2520e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
2521cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2522ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2523b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
2524e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return static_cast<jlong>(env->GetIntField(
2525e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
2526cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2527ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2528b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) {
2529246a0130c5583170f4d168532feb49367fce2b47Andreas Gampe    if (java_object == nullptr) {
2530246a0130c5583170f4d168532feb49367fce2b47Andreas Gampe      return JNIInvalidRefType;
2531246a0130c5583170f4d168532feb49367fce2b47Andreas Gampe    }
2532b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
2533b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    // Do we definitely know what kind of reference this is?
2534b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2535b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    IndirectRefKind kind = GetIndirectRefKind(ref);
2536b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    switch (kind) {
2537c645f1ddb7c40bea6a38eda4b3f83f6b6dec405bMathieu Chartier    case kLocal: {
2538c645f1ddb7c40bea6a38eda4b3f83f6b6dec405bMathieu Chartier      ScopedObjectAccess soa(env);
2539196851b634a5bfdd8ab3fb59a320e550b21b0f4dHiroshi Yamauchi      // The local refs don't need a read barrier.
2540196851b634a5bfdd8ab3fb59a320e550b21b0f4dHiroshi Yamauchi      if (static_cast<JNIEnvExt*>(env)->locals.Get<kWithoutReadBarrier>(ref) !=
2541196851b634a5bfdd8ab3fb59a320e550b21b0f4dHiroshi Yamauchi          kInvalidIndirectRefObject) {
25422ced6a534157d5d963693346904389c19775d2daElliott Hughes        return JNILocalRefType;
25432ced6a534157d5d963693346904389c19775d2daElliott Hughes      }
25442ced6a534157d5d963693346904389c19775d2daElliott Hughes      return JNIInvalidRefType;
2545c645f1ddb7c40bea6a38eda4b3f83f6b6dec405bMathieu Chartier    }
2546b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    case kGlobal:
2547b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      return JNIGlobalRefType;
2548b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    case kWeakGlobal:
2549b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      return JNIWeakGlobalRefType;
2550eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    case kHandleScopeOrInvalid:
2551b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      // Is it in a stack IRT?
2552eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      if (static_cast<JNIEnvExt*>(env)->self->HandleScopeContains(java_object)) {
2553b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes        return JNILocalRefType;
2554b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      }
2555b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      return JNIInvalidRefType;
2556b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    }
25572e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom    LOG(FATAL) << "IndirectRefKind[" << kind << "]";
25582e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom    return JNIInvalidRefType;
2559cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
256000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
256100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private:
256235aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban  static jint EnsureLocalCapacity(ScopedObjectAccess& soa, jint desired_capacity,
256335aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban                                  const char* caller) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
256400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // TODO: we should try to expand the table if necessary.
2565aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes    if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
256600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
256700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return JNI_ERR;
256800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
256900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // TODO: this isn't quite right, since "capacity" includes holes.
257035aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    const size_t capacity = soa.Env()->locals.Capacity();
257100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
257200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (!okay) {
257300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      soa.Self()->ThrowOutOfMemoryError(caller);
257400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
257500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return okay ? JNI_OK : JNI_ERR;
257600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
257700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
257800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  template<typename JniT, typename ArtT>
25792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
25801d99e4549309d05007d041d058b1878de88e9585Ian Rogers    if (UNLIKELY(length < 0)) {
258196a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes      JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
25821d99e4549309d05007d041d058b1878de88e9585Ian Rogers      return nullptr;
258396a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    }
25842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ScopedObjectAccess soa(env);
258550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    ArtT* result = ArtT::Alloc(soa.Self(), length);
258600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<JniT>(result);
258700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
258800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
25892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  template <typename JArrayT, typename ElementT, typename ArtArrayT>
25902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
25912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                           const char* fn_name, const char* operation)
2592b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
259300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
25942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
25952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      JniAbortF(fn_name, "attempt to %s %s primitive array elements with an object of type %s",
25962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                operation, PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
25972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                PrettyDescriptor(array->GetClass()).c_str());
25982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return nullptr;
25992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
26002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
26012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return array;
26022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
26032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
26042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  template <typename ArrayT, typename ElementT, typename ArtArrayT>
26052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
26062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT(java_array);
26072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ScopedObjectAccess soa(env);
26082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
26092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                                            "GetArrayElements",
26102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                                            "get");
26112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (UNLIKELY(array == nullptr)) {
26122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return nullptr;
26132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
2614590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    // Only make a copy if necessary.
2615590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2616590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      if (is_copy != nullptr) {
2617590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        *is_copy = JNI_TRUE;
2618590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      }
26192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      const size_t component_size = sizeof(ElementT);
2620590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      size_t size = array->GetLength() * component_size;
2621590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      void* data = new uint64_t[RoundUp(size, 8) / 8];
2622590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      memcpy(data, array->GetData(), size);
26232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return reinterpret_cast<ElementT*>(data);
2624590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    } else {
2625590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      if (is_copy != nullptr) {
2626590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        *is_copy = JNI_FALSE;
2627590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      }
26282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return reinterpret_cast<ElementT*>(array->GetData());
262900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
263000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
263100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
26322d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  template <typename ArrayT, typename ElementT, typename ArtArrayT>
2633590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
26342d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2635590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    ScopedObjectAccess soa(env);
26362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
26372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                                            "ReleaseArrayElements",
26382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                                            "release");
26392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (array == nullptr) {
26402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return;
26412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
26422d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
26432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
26442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
26452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
26462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                    size_t component_size, void* elements, jint mode)
26472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2648ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    void* array_data = array->GetRawData(component_size, 0);
2649590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    gc::Heap* heap = Runtime::Current()->GetHeap();
26502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    bool is_copy = array_data != elements;
2651590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    size_t bytes = array->GetLength() * component_size;
26522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    VLOG(heap) << "Release primitive array " << soa.Env() << " array_data " << array_data
26532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers               << " elements " << elements;
2654d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier    if (is_copy) {
2655d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier      // Sanity check: If elements is not the same as the java array's data, it better not be a
2656d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier      // heap address. TODO: This might be slow to check, may be worth keeping track of which
2657d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier      // copies we make?
2658d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier      if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
2659d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier        JniAbortF("ReleaseArrayElements", "invalid element pointer %p, array elements are %p",
2660d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier                  reinterpret_cast<void*>(elements), array_data);
2661d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier        return;
2662d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier      }
2663d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier    }
2664590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    // Don't need to copy if we had a direct pointer.
2665590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    if (mode != JNI_ABORT && is_copy) {
2666590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      memcpy(array_data, elements, bytes);
2667590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    }
266800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (mode != JNI_COMMIT) {
2669590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      if (is_copy) {
2670590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        delete[] reinterpret_cast<uint64_t*>(elements);
26713e8b2e1f14176c6beb61a31a27af30bc35998e80Mathieu Chartier      } else if (heap->IsMovableObject(array)) {
26721d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier        // Non copy to a movable object must means that we had disabled the moving GC.
26731d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier        heap->DecrementDisableMovingGC(soa.Self());
2674590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      }
267500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
267600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
267700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
26782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  template <typename JArrayT, typename ElementT, typename ArtArrayT>
26792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
26802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                      jsize start, jsize length, ElementT* buf) {
26812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
26822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ScopedObjectAccess soa(env);
26832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ArtArrayT* array =
26842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
26852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                              "GetPrimitiveArrayRegion",
26862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                              "get region of");
26872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (array != nullptr) {
26882d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      if (start < 0 || length < 0 || start + length > array->GetLength()) {
26892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        ThrowAIOOBE(soa, array, start, length, "src");
26902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      } else {
26912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
26922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        ElementT* data = array->GetData();
26932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        memcpy(buf, data + start, length * sizeof(ElementT));
26942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      }
269500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
269600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
269700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
26982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  template <typename JArrayT, typename ElementT, typename ArtArrayT>
26992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
27002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                      jsize start, jsize length, const ElementT* buf) {
27012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
27022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ScopedObjectAccess soa(env);
27032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ArtArrayT* array =
27042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
27052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                              "SetPrimitiveArrayRegion",
27062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                              "set region of");
27072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (array != nullptr) {
27082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      if (start < 0 || length < 0 || start + length > array->GetLength()) {
27092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        ThrowAIOOBE(soa, array, start, length, "dst");
27102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      } else {
27112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
27122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        ElementT* data = array->GetData();
27132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        memcpy(data + start, buf, length * sizeof(ElementT));
27142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      }
271500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
271600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
2717cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes};
2718ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
271988c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesconst JNINativeInterface gJniNativeInterface = {
2720e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  nullptr,  // reserved0.
2721e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  nullptr,  // reserved1.
2722e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  nullptr,  // reserved2.
2723e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  nullptr,  // reserved3.
2724cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetVersion,
2725cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::DefineClass,
2726cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::FindClass,
2727cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::FromReflectedMethod,
2728cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::FromReflectedField,
2729cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ToReflectedMethod,
2730cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetSuperclass,
2731cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::IsAssignableFrom,
2732cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ToReflectedField,
2733cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::Throw,
2734cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ThrowNew,
2735cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ExceptionOccurred,
2736cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ExceptionDescribe,
2737cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ExceptionClear,
2738cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::FatalError,
2739cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::PushLocalFrame,
2740cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::PopLocalFrame,
2741cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewGlobalRef,
2742cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::DeleteGlobalRef,
2743cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::DeleteLocalRef,
2744cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::IsSameObject,
2745cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewLocalRef,
2746cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::EnsureLocalCapacity,
2747cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::AllocObject,
2748cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewObject,
2749cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewObjectV,
2750cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewObjectA,
2751cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetObjectClass,
2752cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::IsInstanceOf,
2753cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetMethodID,
2754cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallObjectMethod,
2755cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallObjectMethodV,
2756cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallObjectMethodA,
2757cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallBooleanMethod,
2758cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallBooleanMethodV,
2759cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallBooleanMethodA,
2760cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallByteMethod,
2761cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallByteMethodV,
2762cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallByteMethodA,
2763cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallCharMethod,
2764cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallCharMethodV,
2765cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallCharMethodA,
2766cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallShortMethod,
2767cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallShortMethodV,
2768cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallShortMethodA,
2769cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallIntMethod,
2770cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallIntMethodV,
2771cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallIntMethodA,
2772cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallLongMethod,
2773cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallLongMethodV,
2774cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallLongMethodA,
2775cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallFloatMethod,
2776cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallFloatMethodV,
2777cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallFloatMethodA,
2778cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallDoubleMethod,
2779cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallDoubleMethodV,
2780cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallDoubleMethodA,
2781cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallVoidMethod,
2782cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallVoidMethodV,
2783cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallVoidMethodA,
2784cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualObjectMethod,
2785cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualObjectMethodV,
2786cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualObjectMethodA,
2787cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualBooleanMethod,
2788cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualBooleanMethodV,
2789cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualBooleanMethodA,
2790cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualByteMethod,
2791cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualByteMethodV,
2792cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualByteMethodA,
2793cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualCharMethod,
2794cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualCharMethodV,
2795cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualCharMethodA,
2796cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualShortMethod,
2797cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualShortMethodV,
2798cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualShortMethodA,
2799cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualIntMethod,
2800cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualIntMethodV,
2801cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualIntMethodA,
2802cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualLongMethod,
2803cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualLongMethodV,
2804cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualLongMethodA,
2805cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualFloatMethod,
2806cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualFloatMethodV,
2807cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualFloatMethodA,
2808cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualDoubleMethod,
2809cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualDoubleMethodV,
2810cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualDoubleMethodA,
2811cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualVoidMethod,
2812cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualVoidMethodV,
2813cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualVoidMethodA,
2814cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetFieldID,
2815cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetObjectField,
2816cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetBooleanField,
2817cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetByteField,
2818cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetCharField,
2819cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetShortField,
2820cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetIntField,
2821cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetLongField,
2822cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetFloatField,
2823cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetDoubleField,
2824cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetObjectField,
2825cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetBooleanField,
2826cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetByteField,
2827cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetCharField,
2828cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetShortField,
2829cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetIntField,
2830cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetLongField,
2831cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetFloatField,
2832cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetDoubleField,
2833cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticMethodID,
2834cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticObjectMethod,
2835cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticObjectMethodV,
2836cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticObjectMethodA,
2837cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticBooleanMethod,
2838cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticBooleanMethodV,
2839cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticBooleanMethodA,
2840cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticByteMethod,
2841cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticByteMethodV,
2842cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticByteMethodA,
2843cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticCharMethod,
2844cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticCharMethodV,
2845cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticCharMethodA,
2846cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticShortMethod,
2847cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticShortMethodV,
2848cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticShortMethodA,
2849cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticIntMethod,
2850cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticIntMethodV,
2851cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticIntMethodA,
2852cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticLongMethod,
2853cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticLongMethodV,
2854cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticLongMethodA,
2855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticFloatMethod,
2856cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticFloatMethodV,
2857cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticFloatMethodA,
2858cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticDoubleMethod,
2859cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticDoubleMethodV,
2860cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticDoubleMethodA,
2861cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticVoidMethod,
2862cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticVoidMethodV,
2863cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticVoidMethodA,
2864cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticFieldID,
2865cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticObjectField,
2866cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticBooleanField,
2867cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticByteField,
2868cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticCharField,
2869cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticShortField,
2870cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticIntField,
2871cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticLongField,
2872cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticFloatField,
2873cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticDoubleField,
2874cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticObjectField,
2875cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticBooleanField,
2876cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticByteField,
2877cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticCharField,
2878cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticShortField,
2879cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticIntField,
2880cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticLongField,
2881cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticFloatField,
2882cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticDoubleField,
2883cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewString,
2884cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringLength,
2885cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringChars,
2886cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseStringChars,
2887cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewStringUTF,
2888cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringUTFLength,
2889cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringUTFChars,
2890cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseStringUTFChars,
2891cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetArrayLength,
2892cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewObjectArray,
2893cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetObjectArrayElement,
2894cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetObjectArrayElement,
2895cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewBooleanArray,
2896cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewByteArray,
2897cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewCharArray,
2898cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewShortArray,
2899cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewIntArray,
2900cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewLongArray,
2901cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewFloatArray,
2902cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewDoubleArray,
2903cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetBooleanArrayElements,
2904cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetByteArrayElements,
2905cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetCharArrayElements,
2906cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetShortArrayElements,
2907cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetIntArrayElements,
2908cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetLongArrayElements,
2909cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetFloatArrayElements,
2910cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetDoubleArrayElements,
2911cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseBooleanArrayElements,
2912cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseByteArrayElements,
2913cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseCharArrayElements,
2914cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseShortArrayElements,
2915cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseIntArrayElements,
2916cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseLongArrayElements,
2917cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseFloatArrayElements,
2918cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseDoubleArrayElements,
2919cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetBooleanArrayRegion,
2920cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetByteArrayRegion,
2921cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetCharArrayRegion,
2922cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetShortArrayRegion,
2923cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetIntArrayRegion,
2924cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetLongArrayRegion,
2925cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetFloatArrayRegion,
2926cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetDoubleArrayRegion,
2927cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetBooleanArrayRegion,
2928cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetByteArrayRegion,
2929cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetCharArrayRegion,
2930cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetShortArrayRegion,
2931cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetIntArrayRegion,
2932cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetLongArrayRegion,
2933cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetFloatArrayRegion,
2934cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetDoubleArrayRegion,
2935cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::RegisterNatives,
2936cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::UnregisterNatives,
2937cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::MonitorEnter,
2938cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::MonitorExit,
2939cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetJavaVM,
2940cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringRegion,
2941cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringUTFRegion,
2942cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetPrimitiveArrayCritical,
2943cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleasePrimitiveArrayCritical,
2944cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringCritical,
2945cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseStringCritical,
2946cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewWeakGlobalRef,
2947cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::DeleteWeakGlobalRef,
2948cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ExceptionCheck,
2949cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewDirectByteBuffer,
2950cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetDirectBufferAddress,
2951cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetDirectBufferCapacity,
2952cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetObjectRefType,
2953ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro};
2954ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
29557577075b147fd8fa37ca41e7a32d1124676776ceElliott HughesJNIEnvExt::JNIEnvExt(Thread* self, JavaVMExt* vm)
295669f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes    : self(self),
29577577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes      vm(vm),
29585a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers      local_ref_cookie(IRT_FIRST_SEGMENT),
29595a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers      locals(kLocalsInitial, kLocalsMax, kLocal),
29604ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes      check_jni(false),
2961dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers      critical(0),
29625a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers      monitors("monitors", kMonitorsInitial, kMonitorsMax) {
296388c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes  functions = unchecked_functions = &gJniNativeInterface;
29644ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes  if (vm->check_jni) {
296588c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes    SetCheckJniEnabled(true);
2966a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  }
296740ef99eb9dd91c2fa549f40973964529c927bb3cElliott Hughes}
296840ef99eb9dd91c2fa549f40973964529c927bb3cElliott Hughes
2969c1674ed06662420213441ff2b818f2f71f9098dcElliott HughesJNIEnvExt::~JNIEnvExt() {
2970c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes}
2971c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes
2972590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierjobject JNIEnvExt::NewLocalRef(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2973590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  if (obj == nullptr) {
2974590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return nullptr;
2975590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
2976590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  return reinterpret_cast<jobject>(locals.Add(local_ref_cookie, obj));
2977590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier}
2978590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
2979590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartiervoid JNIEnvExt::DeleteLocalRef(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2980590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  if (obj != nullptr) {
2981590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    locals.Remove(local_ref_cookie, reinterpret_cast<IndirectRef>(obj));
2982590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
2983590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier}
298488c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesvoid JNIEnvExt::SetCheckJniEnabled(bool enabled) {
298588c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes  check_jni = enabled;
298688c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes  functions = enabled ? GetCheckJniNativeInterface() : &gJniNativeInterface;
29874ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes}
29884ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes
298973e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughesvoid JNIEnvExt::DumpReferenceTables(std::ostream& os) {
299073e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes  locals.Dump(os);
299173e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes  monitors.Dump(os);
29929d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes}
29939d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes
299435aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Roubanvoid JNIEnvExt::PushFrame(int capacity) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
299535aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban  UNUSED(capacity);  // cpplint gets confused with (int) and thinks its a cast.
29961bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  // TODO: take 'capacity' into account.
29972ced6a534157d5d963693346904389c19775d2daElliott Hughes  stacked_local_ref_cookies.push_back(local_ref_cookie);
29982ced6a534157d5d963693346904389c19775d2daElliott Hughes  local_ref_cookie = locals.GetSegmentState();
29992ced6a534157d5d963693346904389c19775d2daElliott Hughes}
30002ced6a534157d5d963693346904389c19775d2daElliott Hughes
300135aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Roubanvoid JNIEnvExt::PopFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
30022ced6a534157d5d963693346904389c19775d2daElliott Hughes  locals.SetSegmentState(local_ref_cookie);
30032ced6a534157d5d963693346904389c19775d2daElliott Hughes  local_ref_cookie = stacked_local_ref_cookies.back();
30042ced6a534157d5d963693346904389c19775d2daElliott Hughes  stacked_local_ref_cookies.pop_back();
30052ced6a534157d5d963693346904389c19775d2daElliott Hughes}
30062ced6a534157d5d963693346904389c19775d2daElliott Hughes
30072dd0e2cea360bc9206eb88ecc40d259e796c239dIan RogersOffset JNIEnvExt::SegmentStateOffset() {
30082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return Offset(OFFSETOF_MEMBER(JNIEnvExt, locals) +
30092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                IndirectReferenceTable::SegmentStateOffset().Int32Value());
30102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
30112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3012ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro// JNI Invocation interface.
3013ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
3014bddf97641c9371ec74c63bca52fff62fecd73750Brian Carlstromextern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
30152ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
301683a25328c595975097cf3948451088cbfc64fc09Elliott Hughes  if (IsBadJniVersion(args->version)) {
301783a25328c595975097cf3948451088cbfc64fc09Elliott Hughes    LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
30182ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro    return JNI_EVERSION;
30192ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  }
3020e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  RuntimeOptions options;
30212ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  for (int i = 0; i < args->nOptions; ++i) {
30222ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro    JavaVMOption* option = &args->options[i];
3023f1a5adc87760f938b01df26d906295063546b259Elliott Hughes    options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
30242ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  }
30252ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  bool ignore_unrecognized = args->ignoreUnrecognized;
302600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!Runtime::Create(options, ignore_unrecognized)) {
30272ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro    return JNI_ERR;
30282ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  }
302900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Runtime* runtime = Runtime::Current();
3030bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom  bool started = runtime->Start();
3031bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom  if (!started) {
3032bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom    delete Thread::Current()->GetJniEnv();
3033bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom    delete runtime->GetJavaVM();
3034bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom    LOG(WARNING) << "CreateJavaVM failed";
3035bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom    return JNI_ERR;
3036bd86bccf1b47f1151842152ee52cf5d46d6b34abBrian Carlstrom  }
303769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  *p_env = Thread::Current()->GetJniEnv();
303869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  *p_vm = runtime->GetJavaVM();
303969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  return JNI_OK;
30402ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro}
30412ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
3042f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughesextern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize, jsize* vm_count) {
30432ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  Runtime* runtime = Runtime::Current();
3044e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (runtime == nullptr) {
3045f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes    *vm_count = 0;
30462ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  } else {
3047f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes    *vm_count = 1;
304869f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes    vms[0] = runtime->GetJavaVM();
30492ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  }
30502ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  return JNI_OK;
30512ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro}
30522ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
30532ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro// Historically unsupported.
30541bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughesextern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) {
30552ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  return JNI_ERR;
30562ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro}
30572ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
3058cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesclass JII {
3059cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes public:
3060cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jint DestroyJavaVM(JavaVM* vm) {
3061e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (vm == nullptr) {
3062cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      return JNI_ERR;
3063cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
30646a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes    JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
30656a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes    delete raw_vm->runtime;
30666a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes    return JNI_OK;
30672ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  }
30682ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
3069cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
30707577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    return JII_AttachCurrentThread(vm, p_env, thr_args, false);
30712ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  }
30722ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
3073cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
30747577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    return JII_AttachCurrentThread(vm, p_env, thr_args, true);
30752ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  }
30762ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
3077cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jint DetachCurrentThread(JavaVM* vm) {
3078e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (vm == nullptr || Thread::Current() == nullptr) {
3079cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      return JNI_ERR;
3080cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
30816a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes    JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
30826a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes    Runtime* runtime = raw_vm->runtime;
30836a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes    runtime->DetachCurrentThread();
30846a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes    return JNI_OK;
30852ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  }
30862ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
3087cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jint GetEnv(JavaVM* vm, void** env, jint version) {
30883b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes    // GetEnv always returns a JNIEnv* for the most current supported JNI version,
30893b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes    // and unlike other calls that take a JNI version doesn't care if you supply
30903b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes    // JNI_VERSION_1_1, which we don't otherwise support.
30913b7ffa1f4c466f4bf8032c328a47aea83a23868cElliott Hughes    if (IsBadJniVersion(version) && version != JNI_VERSION_1_1) {
309283a25328c595975097cf3948451088cbfc64fc09Elliott Hughes      LOG(ERROR) << "Bad JNI version passed to GetEnv: " << version;
3093cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      return JNI_EVERSION;
3094cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
3095e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (vm == nullptr || env == nullptr) {
3096cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      return JNI_ERR;
3097cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
3098cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    Thread* thread = Thread::Current();
3099e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (thread == nullptr) {
3100e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      *env = nullptr;
3101cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      return JNI_EDETACHED;
3102cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
3103cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    *env = thread->GetJniEnv();
31042ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro    return JNI_OK;
31052ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro  }
3106cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes};
31072ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro
310888c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesconst JNIInvokeInterface gJniInvokeInterface = {
3109e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  nullptr,  // reserved0
3110e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  nullptr,  // reserved1
3111e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  nullptr,  // reserved2
3112cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JII::DestroyJavaVM,
3113cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JII::AttachCurrentThread,
3114cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JII::DetachCurrentThread,
3115cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JII::GetEnv,
3116cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JII::AttachCurrentThreadAsDaemon
3117ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro};
3118ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
3119491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian CarlstromJavaVMExt::JavaVMExt(Runtime* runtime, ParsedOptions* options)
312069f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes    : runtime(runtime),
3121e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      check_jni_abort_hook(nullptr),
3122e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      check_jni_abort_hook_data(nullptr),
31234ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes      check_jni(false),
31247934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom      force_copy(false),  // TODO: add a way to enable this
3125a09576416788b916095739e43a16917e7948f3a4Elliott Hughes      trace(options->jni_trace_),
31268daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes      globals_lock("JNI global reference table lock"),
3127bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes      globals(gGlobalsInitial, gGlobalsMax, kGlobal),
312800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      libraries_lock("JNI shared libraries map lock", kLoadLibraryLock),
3129c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier      libraries(new Libraries),
3130c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier      weak_globals_lock_("JNI weak global reference table lock"),
3131c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier      weak_globals_(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal),
3132c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier      allow_new_weak_globals_(true),
3133c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier      weak_globals_add_condition_("weak globals add condition", weak_globals_lock_) {
313488c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes  functions = unchecked_functions = &gJniInvokeInterface;
31354ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes  if (options->check_jni_) {
313688c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes    SetCheckJniEnabled(true);
3137a2501990dd0f68baf38ce19251949d7bb3ecfe5aElliott Hughes  }
3138f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes}
3139f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
3140de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott HughesJavaVMExt::~JavaVMExt() {
314179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  delete libraries;
3142de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes}
3143de69d7f8c32be83c405bf5a9c5f15fc655f578faElliott Hughes
3144c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartierjweak JavaVMExt::AddWeakGlobalReference(Thread* self, mirror::Object* obj) {
3145c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  if (obj == nullptr) {
3146c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    return nullptr;
3147c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  }
3148c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  MutexLock mu(self, weak_globals_lock_);
3149c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  while (UNLIKELY(!allow_new_weak_globals_)) {
3150c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    weak_globals_add_condition_.WaitHoldingLocks(self);
3151c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  }
3152c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  IndirectRef ref = weak_globals_.Add(IRT_FIRST_SEGMENT, obj);
3153c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  return reinterpret_cast<jweak>(ref);
3154c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier}
3155c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier
3156c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartiervoid JavaVMExt::DeleteWeakGlobalRef(Thread* self, jweak obj) {
3157c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  MutexLock mu(self, weak_globals_lock_);
3158c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  if (!weak_globals_.Remove(IRT_FIRST_SEGMENT, obj)) {
3159c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
3160c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier                 << "failed to find entry";
3161c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  }
3162c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier}
3163c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier
316488c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesvoid JavaVMExt::SetCheckJniEnabled(bool enabled) {
316588c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes  check_jni = enabled;
316688c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes  functions = enabled ? GetCheckJniInvokeInterface() : &gJniInvokeInterface;
31674ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes}
31684ffd31315bc0d00ec278e85feed15985de5ac3dcElliott Hughes
3169ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughesvoid JavaVMExt::DumpForSigQuit(std::ostream& os) {
3170ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  os << "JNI: CheckJNI is " << (check_jni ? "on" : "off");
3171ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  if (force_copy) {
3172ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    os << " (with forcecopy)";
3173ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  }
317450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  Thread* self = Thread::Current();
3175ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  {
3176b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers    ReaderMutexLock mu(self, globals_lock);
3177ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    os << "; globals=" << globals.Capacity();
3178ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  }
3179ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  {
3180c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    MutexLock mu(self, weak_globals_lock_);
3181c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    if (weak_globals_.Capacity() > 0) {
3182c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier      os << " (plus " << weak_globals_.Capacity() << " weak)";
3183ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    }
3184ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  }
3185ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  os << '\n';
3186ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes
3187ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  {
318850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, libraries_lock);
3189ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes    os << "Libraries: " << Dumpable<Libraries>(*libraries) << " (" << libraries->size() << ")\n";
3190ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes  }
3191ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes}
3192ae80b493748c5b6ffe310a91c651e7043f4b2daeElliott Hughes
3193c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartiervoid JavaVMExt::DisallowNewWeakGlobals() {
3194c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  MutexLock mu(Thread::Current(), weak_globals_lock_);
3195c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  allow_new_weak_globals_ = false;
3196c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier}
3197c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier
3198c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartiervoid JavaVMExt::AllowNewWeakGlobals() {
3199c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  Thread* self = Thread::Current();
3200c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  MutexLock mu(self, weak_globals_lock_);
3201c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  allow_new_weak_globals_ = true;
3202c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  weak_globals_add_condition_.Broadcast(self);
3203c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier}
3204c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier
3205c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartiermirror::Object* JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) {
3206c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  MutexLock mu(self, weak_globals_lock_);
3207c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  while (UNLIKELY(!allow_new_weak_globals_)) {
3208c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    weak_globals_add_condition_.WaitHoldingLocks(self);
3209c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier  }
3210ea2e1bd713ca8295ba4fcd01e77a3ce532ea61e4Hiroshi Yamauchi  return weak_globals_.Get(ref);
3211c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier}
3212c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier
321373e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughesvoid JavaVMExt::DumpReferenceTables(std::ostream& os) {
321450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  Thread* self = Thread::Current();
32159d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  {
3216b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers    ReaderMutexLock mu(self, globals_lock);
321773e66f73f5093b64f2b023ebbb85916a13d5c937Elliott Hughes    globals.Dump(os);
32189d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  }
32199d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  {
3220c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    MutexLock mu(self, weak_globals_lock_);
3221c11d9b8870de5f860b13c84003ade7b3f3125a52Mathieu Chartier    weak_globals_.Dump(os);
32229d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes  }
32239d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes}
32249d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes
3225055d46c479369ea825712834353660b45215c195Mathieu Chartierbool JavaVMExt::LoadNativeLibrary(const std::string& path,
32260cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier                                  Handle<mirror::ClassLoader> class_loader,
32271eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers                                  std::string* detail) {
32281eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers  detail->clear();
3229cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
3230cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // See if we've already loaded this library.  If we have, and the class loader
3231cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // matches, return successfully without doing anything.
32327577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  // TODO: for better results we should canonicalize the pathname (or even compare
32337577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  // inodes). This implementation is fine if everybody is using System.loadLibrary.
323479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  SharedLibrary* library;
323550b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  Thread* self = Thread::Current();
323679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  {
323779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // TODO: move the locking (and more of this logic) into Libraries.
323850b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, libraries_lock);
323979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    library = libraries->Get(path);
324079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
3241e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (library != nullptr) {
3242eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    if (library->GetClassLoader() != class_loader.Get()) {
32437577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes      // The library will be associated with class_loader. The JNI
32447577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes      // spec says we can't load the same library into more than one
32457577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes      // class loader.
32461eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers      StringAppendF(detail, "Shared library \"%s\" already opened by "
32477577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes          "ClassLoader %p; can't open in ClassLoader %p",
3248eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier          path.c_str(), library->GetClassLoader(), class_loader.Get());
32497577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes      LOG(WARNING) << detail;
3250cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      return false;
3251cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
32524dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jni) << "[Shared library \"" << path << "\" already loaded in "
3253eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier              << "ClassLoader " << class_loader.Get() << "]";
32541bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes    if (!library->CheckOnLoadResult()) {
32551eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers      StringAppendF(detail, "JNI_OnLoad failed on a previous attempt "
32567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes          "to load \"%s\"", path.c_str());
3257cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      return false;
3258cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
3259cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return true;
3260cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
3261cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
3262cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Open the shared library.  Because we're using a full path, the system
3263cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // doesn't have to search through LD_LIBRARY_PATH.  (It may do so to
3264cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // resolve this library's dependencies though.)
3265cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
3266cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Failures here are expected when java.library.path has several entries
3267cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // and we have to hunt for the lib.
3268cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
326900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Below we dlopen but there is no paired dlclose, this would be necessary if we supported
327000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // class unloading. Libraries will only be unloaded when the reference count (incremented by
327100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // dlopen) becomes zero from dlclose.
327200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
3273cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // This can execute slowly for a large library on a busy system, so we
327400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // want to switch from kRunnable while it executes.  This allows the GC to ignore us.
327500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
3276355383f61d28f2dc8072fbde2639c80627adf16dYong WU  const char* path_str = path.empty() ? nullptr : path.c_str();
3277355383f61d28f2dc8072fbde2639c80627adf16dYong WU  void* handle = dlopen(path_str, RTLD_LAZY);
3278355383f61d28f2dc8072fbde2639c80627adf16dYong WU  bool needs_native_bridge = false;
3279355383f61d28f2dc8072fbde2639c80627adf16dYong WU  if (handle == nullptr) {
328093de4273d72a2558a7b3423547b5074cd76c5796Calin Juravle    if (android::NativeBridgeIsSupported(path_str)) {
328193de4273d72a2558a7b3423547b5074cd76c5796Calin Juravle      handle = android::NativeBridgeLoadLibrary(path_str, RTLD_LAZY);
3282355383f61d28f2dc8072fbde2639c80627adf16dYong WU      needs_native_bridge = true;
3283355383f61d28f2dc8072fbde2639c80627adf16dYong WU    }
3284355383f61d28f2dc8072fbde2639c80627adf16dYong WU  }
328500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  self->TransitionFromSuspendedToRunnable();
3286cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
328784b2f14d57eaf55988c0e0ff80551fde27daffc1Elliott Hughes  VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_LAZY) returned " << handle << "]";
3288cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
3289e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (handle == nullptr) {
32901eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers    *detail = dlerror();
329135d5c3baf701ca3d1e2d5b0b3653a5ca16f21f7eColin Cross    LOG(ERROR) << "dlopen(\"" << path << "\", RTLD_LAZY) failed: " << *detail;
3292cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return false;
3293cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
3294cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
3295cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  // Create a new entry.
329600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // TODO: move the locking (and more of this logic) into Libraries.
329700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  bool created_library = false;
329879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  {
329950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, libraries_lock);
330079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    library = libraries->Get(path);
3301e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (library == nullptr) {  // We won race to get libraries_lock
3302eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      library = new SharedLibrary(path, handle, class_loader.Get());
330300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      libraries->Put(path, library);
330400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      created_library = true;
330579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    }
330600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
330700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!created_library) {
330800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    LOG(INFO) << "WOW: we lost a race to add shared library: "
3309eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier        << "\"" << path << "\" ClassLoader=" << class_loader.Get();
331000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return library->CheckOnLoadResult();
331179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
3312cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
3313eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader.Get()
3314055d46c479369ea825712834353660b45215c195Mathieu Chartier      << "]";
3315cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
33167935372ab784477db452d11112cd60d26be87093Elliott Hughes  bool was_successful = false;
3317355383f61d28f2dc8072fbde2639c80627adf16dYong WU  void* sym = nullptr;
3318355383f61d28f2dc8072fbde2639c80627adf16dYong WU  if (UNLIKELY(needs_native_bridge)) {
3319355383f61d28f2dc8072fbde2639c80627adf16dYong WU    library->SetNeedsNativeBridge();
3320355383f61d28f2dc8072fbde2639c80627adf16dYong WU    sym = library->FindSymbolWithNativeBridge("JNI_OnLoad", nullptr);
3321355383f61d28f2dc8072fbde2639c80627adf16dYong WU  } else {
3322355383f61d28f2dc8072fbde2639c80627adf16dYong WU    sym = dlsym(handle, "JNI_OnLoad");
3323355383f61d28f2dc8072fbde2639c80627adf16dYong WU  }
3324355383f61d28f2dc8072fbde2639c80627adf16dYong WU
3325e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (sym == nullptr) {
33264dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]";
332785affca81271f573c75c32316aa6faa8e52448b1Elliott Hughes    was_successful = true;
332879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  } else {
332979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // Call JNI_OnLoad.  We have to override the current class
333079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // loader, which will always be "null" since the stuff at the
333179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // top of the stack is around Runtime.loadLibrary().  (See
333279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    // the comments in the JNI FindClass function.)
333379082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    typedef int (*JNI_OnLoadFn)(JavaVM*, void*);
333479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym);
3335eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    StackHandleScope<1> hs(self);
3336eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    Handle<mirror::ClassLoader> old_class_loader(hs.NewHandle(self->GetClassLoaderOverride()));
3337eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    self->SetClassLoaderOverride(class_loader.Get());
333879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
3339ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes    int version = 0;
3340ad7c2a3b4daa2abd707375444f4b0db7d69a3838Elliott Hughes    {
334134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes      ScopedThreadStateChange tsc(self, kNative);
33424dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes      VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]";
3343e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      version = (*jni_on_load)(this, nullptr);
334479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    }
334579082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
33461f24296c7c8a6501ee2388c0d20b48f471b48660Mathieu Chartier    if (runtime->GetTargetSdkVersion() != 0 && runtime->GetTargetSdkVersion() <= 21) {
33471f24296c7c8a6501ee2388c0d20b48f471b48660Mathieu Chartier      fault_manager.EnsureArtActionInFrontOfSignalChain();
33481f24296c7c8a6501ee2388c0d20b48f471b48660Mathieu Chartier    }
3349eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    self->SetClassLoaderOverride(old_class_loader.Get());
335079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
33517935372ab784477db452d11112cd60d26be87093Elliott Hughes    if (version == JNI_ERR) {
33521eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers      StringAppendF(detail, "JNI_ERR returned from JNI_OnLoad in \"%s\"", path.c_str());
33537935372ab784477db452d11112cd60d26be87093Elliott Hughes    } else if (IsBadJniVersion(version)) {
33541eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers      StringAppendF(detail, "Bad JNI version returned from JNI_OnLoad in \"%s\": %d",
335575fe90cdb6e358a09047468b750648c8a3bfac9fBrian Carlstrom                    path.c_str(), version);
335679082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      // It's unwise to call dlclose() here, but we can mark it
335779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      // as bad and ensure that future load attempts will fail.
335879082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      // We don't know how far JNI_OnLoad got, so there could
335979082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      // be some partially-initialized stuff accessible through
336079082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      // newly-registered native method calls.  We could try to
336179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes      // unregister them, but that doesn't seem worthwhile.
33627935372ab784477db452d11112cd60d26be87093Elliott Hughes    } else {
33637935372ab784477db452d11112cd60d26be87093Elliott Hughes      was_successful = true;
3364cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
33657935372ab784477db452d11112cd60d26be87093Elliott Hughes    VLOG(jni) << "[Returned " << (was_successful ? "successfully" : "failure")
336675fe90cdb6e358a09047468b750648c8a3bfac9fBrian Carlstrom              << " from JNI_OnLoad in \"" << path << "\"]";
336779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  }
3368cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
33697935372ab784477db452d11112cd60d26be87093Elliott Hughes  library->SetResult(was_successful);
33707935372ab784477db452d11112cd60d26be87093Elliott Hughes  return was_successful;
337179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes}
337279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes
3373e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartiervoid* JavaVMExt::FindCodeForNativeMethod(mirror::ArtMethod* m) {
337479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  CHECK(m->IsNative());
3375e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::Class* c = m->GetDeclaringClass();
33766c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers  // If this is a static method, it could be called before the class has been initialized.
337779082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  if (m->IsStatic()) {
3378c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    c = EnsureInitialized(Thread::Current(), c);
3379c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    if (c == nullptr) {
3380c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      return nullptr;
338179082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes    }
338279082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes  } else {
3383b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers    CHECK(c->IsInitializing()) << c->GetStatus() << " " << PrettyMethod(m);
3384cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
3385161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  std::string detail;
3386161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  void* native_method;
338750b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  Thread* self = Thread::Current();
3388161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  {
338950b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    MutexLock mu(self, libraries_lock);
3390161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom    native_method = libraries->FindNativeMethod(m, detail);
3391161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  }
339262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Throwing can cause libraries_lock to be reacquired.
3393e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (native_method == nullptr) {
339462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    ThrowLocation throw_location = self->GetCurrentLocationForThrow();
339562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    self->ThrowNewException(throw_location, "Ljava/lang/UnsatisfiedLinkError;", detail.c_str());
3396161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  }
3397161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom  return native_method;
3398cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes}
3399cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
340083c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartiervoid JavaVMExt::SweepJniWeakGlobals(IsMarkedCallback* callback, void* arg) {
3401810b1d704f2db0d935bf5dddae3545f79cabd435Mathieu Chartier  MutexLock mu(Thread::Current(), weak_globals_lock_);
3402810b1d704f2db0d935bf5dddae3545f79cabd435Mathieu Chartier  for (mirror::Object** entry : weak_globals_) {
3403196851b634a5bfdd8ab3fb59a320e550b21b0f4dHiroshi Yamauchi    // Since this is called by the GC, we don't need a read barrier.
34046aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier    mirror::Object* obj = *entry;
340583c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier    mirror::Object* new_obj = callback(obj, arg);
34066aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier    if (new_obj == nullptr) {
34076aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier      new_obj = kClearedJniWeakGlobal;
34086aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier    }
34096aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier    *entry = new_obj;
34106aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier  }
34116aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier}
34126aa3df965395566ed6a4fec4af37c2b7577992e9Mathieu Chartier
341383c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartiervoid JavaVMExt::VisitRoots(RootCallback* callback, void* arg) {
341450b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers  Thread* self = Thread::Current();
3415410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes  {
3416b8a0b94735f188bc739e4c55479c37699006b881Ian Rogers    ReaderMutexLock mu(self, globals_lock);
341712f7423a2bb4bfab76700d84eb6d4338d211983aMathieu Chartier    globals.VisitRoots(callback, arg, RootInfo(kRootJNIGlobal));
3418410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes  }
3419410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes  {
34208f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier    MutexLock mu(self, libraries_lock);
34218f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier    // Libraries contains shared libraries which hold a pointer to a class loader.
342283c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier    libraries->VisitRoots(callback, arg);
34238f4be93c8260b84d706d91586aff572791edd9feMathieu Chartier  }
3424410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes  // The weak_globals table is visited by the GC itself (because it mutates the table).
3425410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes}
3426410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes
3427c8fece309fa1d3514071fadaca34530648462b50Elliott Hughesvoid RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
3428bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                           jint method_count) {
3429c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes  ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
3430e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (c.get() == nullptr) {
3431c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes    LOG(FATAL) << "Couldn't find class: " << jni_class_name;
3432c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes  }
3433c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes  JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
3434c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes}
3435c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes
3436df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers}  // namespace art
3437b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
3438b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3439b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  switch (rhs) {
3440b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  case JNIInvalidRefType:
3441b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    os << "JNIInvalidRefType";
3442b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    return os;
3443b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  case JNILocalRefType:
3444b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    os << "JNILocalRefType";
3445b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    return os;
3446b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  case JNIGlobalRefType:
3447b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    os << "JNIGlobalRefType";
3448b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    return os;
3449b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  case JNIWeakGlobalRefType:
3450b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    os << "JNIWeakGlobalRefType";
3451b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    return os;
34522e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom  default:
345324782c6aa7abf396de057d7eb15035b4c594a3b4Shih-wei Liao    LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
34542e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom    return os;
3455b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  }
3456b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
3457