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
26c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h"
273d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier#include "art_method-inl.h"
28ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers#include "atomic.h"
29bad0267eaab9d6a522d05469ff90501deefdb88bMathieu Chartier#include "base/allocator.h"
3007ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h"
3176b6167407c2b6f5d40ad895b2793a6b037f54b2Elliott Hughes#include "base/mutex.h"
321aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h"
339837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers#include "class_linker-inl.h"
344f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
35d000480134b7b00895fbfd142f1d1e18d9cfa6e9Mathieu Chartier#include "fault_handler.h"
3694f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#include "gc_root.h"
371d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/accounting/card_table-inl.h"
38c56057e40938c587a74984651a510e320a8cb4fdMathieu Chartier#include "indirect_reference_table-inl.h"
393dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao#include "interpreter/interpreter.h"
4068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include "jni_env_ext.h"
4168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers#include "java_vm_ext.h"
422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h"
432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h"
4402d2f290380c6aeff5f5a089ee38fa5d55e46130Hiroshi Yamauchi#include "mirror/field-inl.h"
45fc58af45e342ba9e18bbdf597f205a58ec731658Mathieu Chartier#include "mirror/method.h"
462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h"
48b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include "mirror/string-inl.h"
492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/throwable.h"
50491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom#include "parsed_options.h"
5153b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers#include "reflection.h"
522ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro#include "runtime.h"
53a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h"
5400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h"
55a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "ScopedLocalRef.h"
562ed144c2b49ae1da6c464d7a1be0062870530802Carl Shapiro#include "thread.h"
572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "utf.h"
58eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include "well_known_classes.h"
59df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers
60bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughesnamespace art {
61bb1e8f0a07c12a8b0a2dd3cab6a1a7e825a54c6fElliott Hughes
6224555ad5150e6ed31609a1f3c8c1a7e28a939301Mathieu Chartier// Consider turning this on when there is errors which could be related to JNI array copies such as
6324555ad5150e6ed31609a1f3c8c1a7e28a939301Mathieu Chartier// things not rendering correctly. E.g. b/16858794
6424555ad5150e6ed31609a1f3c8c1a7e28a939301Mathieu Chartierstatic constexpr bool kWarnJniAbort = false;
6524555ad5150e6ed31609a1f3c8c1a7e28a939301Mathieu Chartier
666b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
676b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// separated with slashes but aren't wrapped with "L;" like regular descriptors
686b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
696b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// exception; there the "L;" must be present ("[La/b/C;"). Historically we've
706b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes// supported names with dots too (such as "a.b.C").
710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogersstatic std::string NormalizeJniClassDescriptor(const char* name) {
726b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  std::string result;
736b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  // Add the missing "L;" if necessary.
746b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  if (name[0] == '[') {
756b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes    result = name;
766b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  } else {
776b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes    result += 'L';
786b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes    result += name;
796b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes    result += ';';
806b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  }
816b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  // Rewrite '.' as '/' for backwards compatibility.
82a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes  if (result.find('.') != std::string::npos) {
83a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes    LOG(WARNING) << "Call to JNI FindClass with dots in name: "
84a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes                 << "\"" << name << "\"";
85a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes    std::replace(result.begin(), result.end(), '.', '/');
866b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  }
876b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes  return result;
886b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes}
896b436857669d8d1d9be43a70fd8fd33e508276ceElliott Hughes
90e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierstatic void ThrowNoSuchMethodError(ScopedObjectAccess& soa, mirror::Class* c,
9100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                   const char* name, const char* sig, const char* kind)
92b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
931ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers  std::string temp;
940aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray  soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
9562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                 "no %s method \"%s.%s%s\"",
961ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers                                 kind, c->GetDescriptor(&temp), name, sig);
9714134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes}
9814134a10e9bbaff0faf314dc00c1a1aeef8ef86bElliott Hughes
99fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertzstatic void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa, mirror::Class* c,
100fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                                         const char* kind, jint idx, bool return_errors)
101fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
102fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz  LOG(return_errors ? ERROR : FATAL) << "Failed to register native method in "
103fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      << PrettyDescriptor(c) << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
104fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      << ": " << kind << " is null at index " << idx;
1050aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray  soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
106fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz                                 "%s is null at index %d", kind, idx);
107fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz}
108fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz
109c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartierstatic mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass)
110c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
111c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  if (LIKELY(klass->IsInitialized())) {
112c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    return klass;
113c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  }
114eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  StackHandleScope<1> hs(self);
115eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  Handle<mirror::Class> h_klass(hs.NewHandle(klass));
1167b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
117c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    return nullptr;
118c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  }
119eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  return h_klass.Get();
120c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier}
121c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier
12200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
12300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                              const char* name, const char* sig, bool is_static)
124b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
125e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class));
126c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  if (c == nullptr) {
127c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    return nullptr;
128cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1293d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier  ArtMethod* method = nullptr;
1303d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier  auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
131cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  if (is_static) {
1323d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    method = c->FindDirectMethod(name, sig, pointer_size);
133004644fe87046b965442b1ee1008b7206817d187Brian Carlstrom  } else if (c->IsInterface()) {
1343d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    method = c->FindInterfaceMethod(name, sig, pointer_size);
135cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  } else {
1363d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    method = c->FindVirtualMethod(name, sig, pointer_size);
137e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (method == nullptr) {
138cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // No virtual method matching the signature.  Search declared
139cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // private methods and constructors.
1403d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier      method = c->FindDeclaredDirectMethod(name, sig, pointer_size);
141cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
142cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
143e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (method == nullptr || method->IsStatic() != is_static) {
14400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
145e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return nullptr;
146cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
14700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return soa.EncodeMethod(method);
148ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro}
149ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
150e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierstatic mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
151b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1523d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier  ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
153ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
154ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
15568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    return soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
15600fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom  }
157ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  // If we have a method, use its ClassLoader for context.
158e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (method != nullptr) {
159ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    return method->GetDeclaringClass()->GetClassLoader();
160ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  }
161ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  // We don't have a method, so try to use the system ClassLoader.
162e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::ClassLoader* class_loader =
163e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
164e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (class_loader != nullptr) {
165ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    return class_loader;
166ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  }
167ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  // See if the override ClassLoader is set for gtests.
16868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  class_loader = soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
169e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (class_loader != nullptr) {
17081c6f8db12b203878a7d72444ead2bc7cf5c47adAndreas Gampe    // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
17181c6f8db12b203878a7d72444ead2bc7cf5c47adAndreas Gampe    // image.
17281c6f8db12b203878a7d72444ead2bc7cf5c47adAndreas Gampe    CHECK(Runtime::Current()->IsAotCompiler());
1734585f876eb5dfb936bd0d6cb6acd78a1f2182ba6Andreas Gampe    CHECK(!Runtime::Current()->IsCompilingBootImage());
174ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom    return class_loader;
175ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  }
176ce88853ab316c70ef7b598978a3609611db60552Brian Carlstrom  // Use the BOOTCLASSPATH.
177e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  return nullptr;
17800fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom}
17900fae585c6e4a37b964c77f557fbf84f11e2d930Brian Carlstrom
18000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
18100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                            const char* sig, bool is_static)
182b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
183eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  StackHandleScope<2> hs(soa.Self());
184eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  Handle<mirror::Class> c(
185eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class))));
186eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier  if (c.Get() == nullptr) {
187c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    return nullptr;
188cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
189c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* field = nullptr;
190e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::Class* field_type;
1910cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1920cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  if (sig[1] != '\0') {
193eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
1949837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers    field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
1950cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  } else {
1960cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    field_type = class_linker->FindPrimitiveClass(*sig);
1970cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
198e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (field_type == nullptr) {
1990cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers    // Failed to find type from the signature of the field.
20000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    DCHECK(soa.Self()->IsExceptionPending());
201277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe    StackHandleScope<1> hs2(soa.Self());
20214691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray    Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
20300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Self()->ClearException();
2041ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers    std::string temp;
2050aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray    soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
206491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                                   "no type \"%s\" found and so no field \"%s\" "
207491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                                   "could be found in class \"%s\" or its superclasses", sig, name,
2081ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers                                   c->GetDescriptor(&temp));
20914691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray    soa.Self()->GetException()->SetCause(cause.Get());
210e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return nullptr;
2110cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers  }
2121ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers  std::string temp;
213cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  if (is_static) {
214f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier    field = mirror::Class::FindStaticField(soa.Self(), c, name,
2151ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers                                           field_type->GetDescriptor(&temp));
2164dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  } else {
2171ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers    field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
2184dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
219e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (field == nullptr) {
2200aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray    soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
22162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                   "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
2221ff3c98775a4577cf053dba9a0c2d5c21c07b298Ian Rogers                                   sig, name, c->GetDescriptor(&temp));
223e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return nullptr;
224cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
22500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return soa.EncodeField(field);
226ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro}
227ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
228e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartierstatic void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
22900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        jsize length, const char* identifier)
230b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
23154e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes  std::string type(PrettyTypeOf(array));
2320aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray  soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
23362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                 "%s offset=%d length=%d %s.length=%d",
23462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                 type.c_str(), start, length, identifier, array->GetLength());
235814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes}
2360571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers
23700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersstatic void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
23800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                        jsize array_length)
239b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2400aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray  soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
24162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                 "offset=%d length=%d string.length()=%d", start, length,
24262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                                 array_length);
243b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
244814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
24500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersint ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
246b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers    LOCKS_EXCLUDED(Locks::mutator_lock_) {
24700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Turn the const char* into a java.lang.String.
24800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
249e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (msg != nullptr && s.get() == nullptr) {
25000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return JNI_ERR;
251814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  }
252814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
25300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Choose an appropriate constructor and set up the arguments.
25400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jvalue args[2];
25500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const char* signature;
256e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (msg == nullptr && cause == nullptr) {
25700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    signature = "()V";
258e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  } else if (msg != nullptr && cause == nullptr) {
25900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    signature = "(Ljava/lang/String;)V";
26000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    args[0].l = s.get();
261e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  } else if (msg == nullptr && cause != nullptr) {
26200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    signature = "(Ljava/lang/Throwable;)V";
26300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    args[0].l = cause;
264814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  } else {
26500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
26600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    args[0].l = s.get();
26700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    args[1].l = cause;
26800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
26900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
270e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (mid == nullptr) {
271ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers    ScopedObjectAccess soa(env);
27200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    LOG(ERROR) << "No <init>" << signature << " in "
273e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        << PrettyClass(soa.Decode<mirror::Class*>(exception_class));
27400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return JNI_ERR;
275814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  }
276a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes
277e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  ScopedLocalRef<jthrowable> exception(
278e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
279e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (exception.get() == nullptr) {
28000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return JNI_ERR;
28100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
282ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers  ScopedObjectAccess soa(env);
28314691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray  soa.Self()->SetException(soa.Decode<mirror::Throwable*>(exception.get()));
28400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  return JNI_OK;
285a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes}
286a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes
28768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogersstatic JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
28868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  return reinterpret_cast<JNIEnvExt*>(env)->vm;
2897577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes}
2907577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes
2912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers#define CHECK_NON_NULL_ARGUMENT(value) \
2922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
2933b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier
2942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers#define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
2952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
2962d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
2972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers#define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
2982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
2992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
3002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers#define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
3012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
3022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
3032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers#define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
304e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (UNLIKELY(value == nullptr)) { \
30568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    JavaVmExtFromEnv(env)->JniAbortF(name, #value " == null"); \
3062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return return_val; \
307bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  }
308bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers
3093b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
310e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (UNLIKELY(length != 0 && value == nullptr)) { \
31168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    JavaVmExtFromEnv(env)->JniAbortF(__FUNCTION__, #value " == null"); \
3122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return; \
3134ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers  }
3144ffdc6bd962c37bca407267c0858b37bb18a9857Ian Rogers
31582566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampetemplate <bool kNative>
3163d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartierstatic ArtMethod* FindMethod(mirror::Class* c, const StringPiece& name, const StringPiece& sig)
31782566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
3183d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier  auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
3193d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier  for (auto& method : c->GetDirectMethods(pointer_size)) {
3203d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
3213d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier      return &method;
32282566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe    }
32382566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe  }
3243d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier  for (auto& method : c->GetVirtualMethods(pointer_size)) {
3253d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
3263d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier      return &method;
32782566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe    }
32882566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe  }
32982566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe  return nullptr;
33082566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe}
33182566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe
332cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughesclass JNI {
333cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes public:
33425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers  static jint GetVersion(JNIEnv*) {
335cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return JNI_VERSION_1_6;
336cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
337cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
33825e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers  static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
339cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    LOG(WARNING) << "JNI DefineClass is not supported";
340e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return nullptr;
34118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
34218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
343cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jclass FindClass(JNIEnv* env, const char* name) {
3443b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(name);
3455fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    Runtime* runtime = Runtime::Current();
3465fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    ClassLinker* class_linker = runtime->GetClassLinker();
347cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    std::string descriptor(NormalizeJniClassDescriptor(name));
348ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedObjectAccess soa(env);
349e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = nullptr;
3505fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    if (runtime->IsStarted()) {
351eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      StackHandleScope<1> hs(soa.Self());
352eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier      Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
3539837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers      c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
3545fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    } else {
3559837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers      c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
3565fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes    }
35700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jclass>(c);
358cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
359ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
36062f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
3613b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(jlr_method);
36200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
3633d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    return soa.EncodeMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
36418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
36518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
36662f0512bf6d9bc6141358bf22e93afa70dc58b1aIan Rogers  static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
3673b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(jlr_field);
36800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
369daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier    mirror::Object* obj_field = soa.Decode<mirror::Object*>(jlr_field);
370daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier    if (obj_field->GetClass() != mirror::Field::StaticClass()) {
3712cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier      // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
372daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier      return nullptr;
373daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier    }
374daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier    auto* field = static_cast<mirror::Field*>(obj_field);
375daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier    return soa.EncodeField(field->GetArtField());
376cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
37718c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
378cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
3793b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
38000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
3813d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    ArtMethod* m = soa.DecodeMethod(mid);
382fc58af45e342ba9e18bbdf597f205a58ec731658Mathieu Chartier    mirror::AbstractMethod* method;
383d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz    if (m->IsConstructor()) {
384fc58af45e342ba9e18bbdf597f205a58ec731658Mathieu Chartier      method = mirror::Constructor::CreateFromArtMethod(soa.Self(), m);
385d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz    } else {
386fc58af45e342ba9e18bbdf597f205a58ec731658Mathieu Chartier      method = mirror::Method::CreateFromArtMethod(soa.Self(), m);
387d3333767dc25566ad207c90c897adaefd813588dSebastien Hertz    }
388fc58af45e342ba9e18bbdf597f205a58ec731658Mathieu Chartier    return soa.AddLocalReference<jobject>(method);
38918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
390ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
391cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
3923b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(fid);
39300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
394c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier    ArtField* f = soa.DecodeField(fid);
395daaf3265806eb2eadb2e03302bd68022fab5ca28Mathieu Chartier    return soa.AddLocalReference<jobject>(mirror::Field::CreateFromArtField(soa.Self(), f, true));
396cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
397cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
39837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
3993b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_object);
40000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
401e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
40200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jclass>(o->GetClass());
40337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  }
40437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
405885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
4063b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
40700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
408e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
40900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jclass>(c->GetSuperClass());
41018c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
41118c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
4121268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // Note: java_class1 should be safely castable to java_class2, and
4131268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath  // not the other way around.
41437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
4152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
4162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
41700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
418e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
419e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
4201268b742c8cff7318dc0b5b283cbaeabfe0725baNarayan Kamath    return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
421cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
42218c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
423e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes  static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
4242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
425e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (jobj == nullptr) {
4265d40f182181488eb39ccd19ffd306bb1fb9740c9Brian Carlstrom      // Note: JNI is different from regular Java instanceof in this respect
42737f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes      return JNI_TRUE;
42837f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    } else {
429ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom      ScopedObjectAccess soa(env);
430e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
431e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
432e84278b035c8a48f6032ef98fae008d875fba7a4Elliott Hughes      return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
43337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    }
43437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  }
43537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
43637f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static jint Throw(JNIEnv* env, jthrowable java_exception) {
43700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
438e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
439e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (exception == nullptr) {
44037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes      return JNI_ERR;
44137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    }
44214691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray    soa.Self()->SetException(exception);
44337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes    return JNI_OK;
44437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  }
44537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
446e5b0dc83537bf915c6abe4efeae6e501daf75a27Elliott Hughes  static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
4472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
448e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return ThrowNewException(env, c, msg, nullptr);
44937f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  }
45037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
45137f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static jboolean ExceptionCheck(JNIEnv* env) {
452120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers    return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
45337f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  }
45437f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes
45537f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static void ExceptionClear(JNIEnv* env) {
456a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov    ScopedObjectAccess soa(env);
457a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov    soa.Self()->ClearException();
45818c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
45918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
46037f7a40f6789bb287f287a9af00777af9d6428eeElliott Hughes  static void ExceptionDescribe(JNIEnv* env) {
46100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
46272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
4633a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov    // If we have no exception to describe, pass through.
46414691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray    if (!soa.Self()->GetException()) {
4653a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov      return;
4663a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov    }
4673a1444ccb92fb1b11d4943c3baa1f0a3abed4f10Alexei Zavjalov
46814691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray    StackHandleScope<1> hs(soa.Self());
46914691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray    Handle<mirror::Throwable> old_exception(
47014691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray        hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
47114691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray    soa.Self()->ClearException();
472491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom    ScopedLocalRef<jthrowable> exception(env,
473eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                                         soa.AddLocalReference<jthrowable>(old_exception.Get()));
47472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
47572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
476e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (mid == nullptr) {
47772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes      LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
478eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier                   << PrettyTypeOf(old_exception.Get());
47972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    } else {
48072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes      env->CallVoidMethod(exception.get(), mid);
48162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      if (soa.Self()->IsExceptionPending()) {
48214691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray        LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException())
48372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes                     << " thrown while calling printStackTrace";
48462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers        soa.Self()->ClearException();
48572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes      }
48672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    }
48714691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray    soa.Self()->SetException(old_exception.Get());
488cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
48918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
490cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jthrowable ExceptionOccurred(JNIEnv* env) {
49100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
49214691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray    mirror::Object* exception = soa.Self()->GetException();
49300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jthrowable>(exception);
49418c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes  }
49518c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
49625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers  static void FatalError(JNIEnv*, const char* msg) {
497cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    LOG(FATAL) << "JNI FatalError called: " << msg;
498cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
49918c0753c1659629021b4becdaa3f6ea81aecce35Elliott Hughes
5002ced6a534157d5d963693346904389c19775d2daElliott Hughes  static jint PushLocalFrame(JNIEnv* env, jint capacity) {
50135aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    // TODO: SOA may not be necessary but I do it to please lock annotations.
50235aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    ScopedObjectAccess soa(env);
50368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
5042ced6a534157d5d963693346904389c19775d2daElliott Hughes      return JNI_ERR;
5052ced6a534157d5d963693346904389c19775d2daElliott Hughes    }
50668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
507cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return JNI_OK;
508c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes  }
509c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes
5102ced6a534157d5d963693346904389c19775d2daElliott Hughes  static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
51100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
512e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor);
51300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Env()->PopFrame();
51400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(survivor);
515cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
516c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes
5172ced6a534157d5d963693346904389c19775d2daElliott Hughes  static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
51835aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    // TODO: SOA may not be necessary but I do it to please lock annotations.
51935aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    ScopedObjectAccess soa(env);
52068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
52172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  }
52272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes
523cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
52425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
525e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
52668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
527c5f7c91ab89055cffb573fff7e06dbdd860bccedElliott Hughes  }
528ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
529cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
53068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
53168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    Thread* self = down_cast<JNIEnvExt*>(env)->self;
53268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    vm->DeleteGlobalRef(self, obj);
533cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
534ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
535cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
53600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
53768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
53868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
539cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
540ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
541cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
54268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
54368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    Thread* self = down_cast<JNIEnvExt*>(env)->self;
54468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    vm->DeleteWeakGlobalRef(self, obj);
545cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
546ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
547cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jobject NewLocalRef(JNIEnv* env, jobject obj) {
54825e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
549e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
550e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    // Check for null after decoding the object to handle cleared weak globals.
551e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    if (decoded_obj == nullptr) {
552e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier      return nullptr;
553e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    }
554e8c48db6bb507d7fa20c78481c58c23be0045f67Mathieu Chartier    return soa.AddLocalReference<jobject>(decoded_obj);
5554dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
556ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
557e290896bfccb170f589407c0d10945c8ae0c5807Mathieu Chartier  static void DeleteLocalRef(JNIEnv* env, jobject obj) {
558e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (obj == nullptr) {
559cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      return;
560cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
561e290896bfccb170f589407c0d10945c8ae0c5807Mathieu Chartier    // SOA is only necessary to have exclusion between GC root marking and removing.
562e290896bfccb170f589407c0d10945c8ae0c5807Mathieu Chartier    // We don't want to have the GC attempt to mark a null root if we just removed
563e290896bfccb170f589407c0d10945c8ae0c5807Mathieu Chartier    // it. b/22119403
564e290896bfccb170f589407c0d10945c8ae0c5807Mathieu Chartier    ScopedObjectAccess soa(env);
565e290896bfccb170f589407c0d10945c8ae0c5807Mathieu Chartier    auto* ext_env = down_cast<JNIEnvExt*>(env);
566e290896bfccb170f589407c0d10945c8ae0c5807Mathieu Chartier    if (!ext_env->locals.Remove(ext_env->local_ref_cookie, obj)) {
567cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // Attempting to delete a local reference that is not in the
568cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // topmost local reference frame is a no-op.  DeleteLocalRef returns
569cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // void and doesn't throw any exceptions, but we should probably
570cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // complain about it so the user will notice that things aren't
571cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      // going quite the way they expect.
572cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
573cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes                   << "failed to find entry";
574cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
57583ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro  }
576cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
577cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
578ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    if (obj1 == obj2) {
579ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom      return JNI_TRUE;
580ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    } else {
581ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom      ScopedObjectAccess soa(env);
582491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom      return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
583491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom              ? JNI_TRUE : JNI_FALSE;
584ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    }
58583ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro  }
586cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
587885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jobject AllocObject(JNIEnv* env, jclass java_class) {
5883b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
58900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
590e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
591c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    if (c == nullptr) {
592c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      return nullptr;
593885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    }
594848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    if (c->IsStringClass()) {
595848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
596848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      mirror::SetStringCountVisitor visitor(0);
597848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      return soa.AddLocalReference<jobject>(mirror::String::Alloc<true>(soa.Self(), 0,
598848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao                                                                        allocator_type, visitor));
599848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    }
60050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
601cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
602cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
603bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
604cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list args;
60572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(args, mid);
6063b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
6073b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
608bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    jobject result = NewObjectV(env, java_class, mid, args);
609cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(args);
610cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return result;
611cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
612cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
61372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
6143b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
6153b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
61600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
617e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
618c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    if (c == nullptr) {
619c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      return nullptr;
620885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    }
621848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    if (c->IsStringClass()) {
622848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      // Replace calls to String.<init> with equivalent StringFactory call.
623848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
624848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
625848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    }
626e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* result = c->AllocObject(soa.Self());
627c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    if (result == nullptr) {
628c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      return nullptr;
62930646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes    }
63000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject local_result = soa.AddLocalReference<jobject>(result);
63172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
632e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (soa.Self()->IsExceptionPending()) {
633c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      return nullptr;
6345d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers    }
635e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return local_result;
636cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
637cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
63872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
6393b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
6403b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
64100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
642e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
643c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier    if (c == nullptr) {
644c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      return nullptr;
645885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes    }
646848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    if (c->IsStringClass()) {
647848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      // Replace calls to String.<init> with equivalent StringFactory call.
648848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
649848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
650848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    }
651e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* result = c->AllocObject(soa.Self());
652e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (result == nullptr) {
653e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      return nullptr;
65430646836b4a1c6e5e80ddaea246cf9669eaa0628Elliott Hughes    }
65500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject local_result = soa.AddLocalReference<jobjectArray>(result);
65672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
657e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (soa.Self()->IsExceptionPending()) {
658e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      return nullptr;
6595d4bdc29737a693027daaf6ed3f0792368eb4baeIan Rogers    }
660e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return local_result;
661cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
662cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
663bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
6643b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
6653b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(name);
6663b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(sig);
66700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
668bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    return FindMethodID(soa, java_class, name, sig, false);
669cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
670ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
671bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
672bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                     const char* sig) {
6733b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
6743b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(name);
6753b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(sig);
67600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
677bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    return FindMethodID(soa, java_class, name, sig, true);
678cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
679ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
68072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
68172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
68272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
6833b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
6843b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
68525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
68600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
68772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
68800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
689cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
690ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
69172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
6923b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
6933b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
69400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
69500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
69600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
697cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
698ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
69972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
7003b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
7013b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
70200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
70315e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
70400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
705cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
706ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
70772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
70872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
70972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
7102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
7112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
71225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
71300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
71472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
715f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetZ();
716cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
717ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
71872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
7192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
7202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
72100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
72200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
723cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
724ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
72572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
7262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
7272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
72800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
72915e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
730cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
731ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
73272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
73372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
73472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
7352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
7362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
737bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    ScopedObjectAccess soa(env);
73800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
73972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
740f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetB();
741cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
742ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
74372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
7442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
7452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
74600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
74700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
748cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
749ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
75072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
7512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
7522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
75300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
75415e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
755cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
756ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
75772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
75872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
75972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
7602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
7612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
76225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
76300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
76472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
765f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetC();
766cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
767ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
76872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
7692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
7702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
77100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
77200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
773cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
774ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
77572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
7762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
7772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
77800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
77915e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
780cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
781ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
78272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
78372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
78472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
7852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
7862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
78725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
78800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
78972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
790f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetD();
791cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
792ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
79372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
7942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
7952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
79600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
79700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
798cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
799ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
80072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
8012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
80300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
80415e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
805cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
806ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
80772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
80872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
80972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
8102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
812bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    ScopedObjectAccess soa(env);
81300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
81472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
815f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetF();
816cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
817ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
81872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
8192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
82100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
82200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
823cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
824ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
82572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
8262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
82800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
82915e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
830cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
831ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
83272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
83372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
83472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
8352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8362d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
83725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
83800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
83972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
840f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetI();
841cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
842ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
84372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
8442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
84600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
84700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
848cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
849ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
85072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
8512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
85300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
85415e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
856ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
85772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
85872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
85972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
8602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
86225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
86300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
86472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
865f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetJ();
866cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
867ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
86872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
8692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
87100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
87200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
873cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
874ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
87572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
8762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
87800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
87915e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
880cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
881ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
88272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
88372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
88472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
8852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
88725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
88800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
88972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
890f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetS();
891cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
892ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
89372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
8942d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
8952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
89600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
89700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
898cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
899ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
90072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
9012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
9022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
90300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
90415e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
905cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
906ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
90772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
90872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_list ap;
90972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
9102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
9112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
91225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
9131b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers    InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
91472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_end(ap);
915cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
916ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
91772025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
9182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
9192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
92000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
92100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
922cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
923ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
92472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes  static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
9252d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
9262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
92700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
92815e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
929cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
930ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
9311bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
932cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
93372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
9343b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
9353b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
93625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
93700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
93800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
939cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
940cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return local_result;
941cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
942ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
943bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
944bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                             va_list args) {
9453b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
9463b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
94700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
94800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, args));
94900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
950cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
951ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
952bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
953bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                             jvalue* args) {
9543b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
9553b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
95600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
95715e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    JValue result(InvokeWithJValues(soa, obj, mid, args));
95800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
959cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
960ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
961bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
962bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                              ...) {
963cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
96472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
9652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
9662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
96725e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
96800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
969cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
970f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetZ();
971cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
972ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
973bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
974bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                               va_list args) {
9752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
9762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
97700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
97800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
979cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
980ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
981bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
982bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                               jvalue* args) {
9832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
9842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
98500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
98615e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeWithJValues(soa, obj, mid, args).GetZ();
987cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
988ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
9891bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
990cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
99172025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
9922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
9932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
99425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
99500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
996cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
997f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetB();
998cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
999ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1000bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1001bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         va_list args) {
10022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
100400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
100500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetB();
1006cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1007ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1008bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1009bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         jvalue* args) {
10102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
101200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
101315e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeWithJValues(soa, obj, mid, args).GetB();
1014cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1015ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
10161bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1017cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
101872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
10192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1021bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    ScopedObjectAccess soa(env);
102200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1023cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1024f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetC();
1025cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1026ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1027bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1028bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         va_list args) {
10292d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10302d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
103100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
103200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetC();
1033cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1034ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1035bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1036bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         jvalue* args) {
10372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
103900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
104015e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeWithJValues(soa, obj, mid, args).GetC();
1041cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1042ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
10431bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1044cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
104572025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
10462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
104825e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
104900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1050cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1051f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetS();
1052cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1053ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1054bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1055bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                           va_list args) {
10562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
105800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
105900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetS();
1060cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1061ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1062bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1063bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                           jvalue* args) {
10642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
106600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
106715e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeWithJValues(soa, obj, mid, args).GetS();
1068cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1069ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
10701bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1071cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
107272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
10732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
107525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
107600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1077cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1078f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetI();
1079cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1080ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1081bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1082bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                       va_list args) {
10832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
108500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
108600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetI();
1087cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1088ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1089bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1090bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                       jvalue* args) {
10912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
10922d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
109300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
109415e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeWithJValues(soa, obj, mid, args).GetI();
1095cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1096ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
10971bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1098cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
109972025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
11002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
110225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
110300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1104cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1105f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetJ();
1106cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1107ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1108bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1109bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         va_list args) {
11102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
111200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
111300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
1114cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1115ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1116bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1117bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                         jvalue* args) {
11182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
112000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
112115e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeWithJValues(soa, obj, mid, args).GetJ();
1122cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1123ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
11241bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1125cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
112672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
11272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
112925e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
113000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1131cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1132f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetF();
1133cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1134ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1135bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1136bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                           va_list args) {
11372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
113900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
114000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetF();
1141cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1142ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1143bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1144bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                           jvalue* args) {
11452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
114700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
114815e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeWithJValues(soa, obj, mid, args).GetF();
1149cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1150ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
11511bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1152cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
115372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
11542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
115625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
115700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1158cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1159f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetD();
1160cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1161ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1162bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1163bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                             va_list args) {
11642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
116600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
116700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return InvokeWithVarArgs(soa, obj, mid, args).GetD();
1168cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1169ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1170bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1171bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                             jvalue* args) {
11722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
11732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
117400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
117515e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    return InvokeWithJValues(soa, obj, mid, args).GetD();
1176cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1177ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
11781bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1179cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
118072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
11812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
11822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
118325e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
118400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    InvokeWithVarArgs(soa, obj, mid, ap);
1185cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1186cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1187ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1188ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1189ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                                        va_list args) {
11902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
11912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
119200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
119300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    InvokeWithVarArgs(soa, obj, mid, args);
1194cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1195ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1196bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1197bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                        jvalue* args) {
11982d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
11992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
120000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
120115e9ad1d028d7f12cb598b075453173532a00d91Jeff Hao    InvokeWithJValues(soa, obj, mid, args);
1202cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1203ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1204bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
12053b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
12063b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(name);
12073b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(sig);
120800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1209bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    return FindFieldID(soa, java_class, name, sig, false);
1210cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1211ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1212bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1213bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                   const char* sig) {
12143b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_class);
12153b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(name);
12163b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(sig);
121700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1218bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    return FindFieldID(soa, java_class, name, sig, true);
1219cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1220ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1221885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
12223b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(obj);
12233b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(fid);
122400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1225e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* o = soa.Decode<mirror::Object*>(obj);
1226c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier    ArtField* f = soa.DecodeField(fid);
122700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(f->GetObject(o));
1228cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1229ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1230885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
12313b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(fid);
123200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1233c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier    ArtField* f = soa.DecodeField(fid);
12342fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
1235cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1236ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1237885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
12382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
12392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
124000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1241e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1242e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1243c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier    ArtField* f = soa.DecodeField(fid);
1244d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetObject<false>(o, v);
1245cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1246ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1247885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
12482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
124900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1250e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1251c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier    ArtField* f = soa.DecodeField(fid);
1252d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    f->SetObject<false>(f->GetDeclaringClass(), v);
1253cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1254ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1255885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes#define GET_PRIMITIVE_FIELD(fn, instance) \
12562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
12572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
125800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env); \
1259e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1260c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* f = soa.DecodeField(fid); \
1261bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  return f->Get ##fn (o)
1262885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
12632fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#define GET_STATIC_PRIMITIVE_FIELD(fn) \
12642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
12652fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  ScopedObjectAccess soa(env); \
1266c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* f = soa.DecodeField(fid); \
1267bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  return f->Get ##fn (f->GetDeclaringClass())
12682fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers
1269885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes#define SET_PRIMITIVE_FIELD(fn, instance, value) \
12702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
12712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
127200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(env); \
1273e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1274c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* f = soa.DecodeField(fid); \
1275d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  f->Set ##fn <false>(o, value)
1276885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
12772fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
12782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
12792fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  ScopedObjectAccess soa(env); \
1280c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier  ArtField* f = soa.DecodeField(fid); \
1281d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  f->Set ##fn <false>(f->GetDeclaringClass(), value)
12822fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers
1283885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
1284bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Boolean, obj);
1285cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1286ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1287885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
1288bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Byte, obj);
1289cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1290ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1291885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
1292bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Char, obj);
1293cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1294ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1295885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
1296bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Short, obj);
1297cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1298ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1299885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
1300bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Int, obj);
1301cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1302ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1303885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
1304bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Long, obj);
1305cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1306ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1307885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
1308bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Float, obj);
1309cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1310ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1311885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
1312bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_PRIMITIVE_FIELD(Double, obj);
1313cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1314ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
13151bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
1316bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Boolean);
1317cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1318ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
13191bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
1320bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Byte);
132183ab4f3b4e5544dc78c059e139f20cf93e5c6ce6Carl Shapiro  }
1322cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
13231bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
1324bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Char);
13259b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro  }
1326ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
13271bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
1328bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Short);
1329cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1330ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
13311bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
1332bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Int);
1333cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1334ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
13351bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
1336bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Long);
1337885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1338885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
13391bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
1340bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Float);
1341885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1342885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
13431bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
1344bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    GET_STATIC_PRIMITIVE_FIELD(Double);
1345885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1346885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1347885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
1348bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Boolean, obj, v);
1349885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1350885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1351885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
1352bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Byte, obj, v);
1353885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1354885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1355885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
1356bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Char, obj, v);
1357885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1358885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1359885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
1360bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Float, obj, v);
1361885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1362885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1363885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
1364bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Double, obj, v);
1365885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1366885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1367885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
1368bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Int, obj, v);
1369885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1370885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1371885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
1372bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Long, obj, v);
1373885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1374885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1375885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
1376bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_PRIMITIVE_FIELD(Short, obj, v);
1377885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1378885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1379885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
1380bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
1381885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1382885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1383885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
1384bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Byte, v);
1385885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1386885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1387885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
1388bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Char, v);
1389885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1390885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1391885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
1392bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Float, v);
1393885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1394885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1395885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
1396bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Double, v);
1397885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1398885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1399885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
1400bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Int, v);
1401885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1402885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1403885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
1404bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Long, v);
1405885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  }
1406885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes
1407885c3bd4d7adcc7f60f656b4f7247e7065feadf3Elliott Hughes  static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
1408bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    SET_STATIC_PRIMITIVE_FIELD(Short, v);
1409cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1410ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14111bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1412cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
141372025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
14143b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
141525e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1416e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
141700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1418cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1419cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return local_result;
1420cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1421ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14221bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
14233b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
142400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1425e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
142600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
1427cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1428ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14291bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
14303b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(mid);
143100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1432e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithJValues(soa, nullptr, mid, args));
143300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(result.GetL());
1434cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1435ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14361bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1437cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
143872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
14392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
144025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1441e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1442cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1443f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetZ();
1444cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1445ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14461bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
14472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
144800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1449e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
1450cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1451ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14521bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
14532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
145400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1455e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
1456cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1457ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14581bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1459cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
146072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
14612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
146225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1463e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1464cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1465f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetB();
1466cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1467ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14681bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
14692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
147000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1471e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
1472cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1473ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14741bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
14752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
147600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1477e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetB();
1478cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1479ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14801bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1481cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
148272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
14832d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
148425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1485e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1486cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1487f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetC();
1488cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1489ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14901bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
14912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
149200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1493e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
1494cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1495ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
14961bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
14972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
149800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1499e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetC();
1500cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1501ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15021bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1503cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
150472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
15052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
150625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1507e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1508cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1509f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetS();
1510cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1511ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15121bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
15132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
151400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1515e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
1516cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1517ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15181bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
15192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
152000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1521e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetS();
1522cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1523ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15241bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1525cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
152672025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
15272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
152825e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1529e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1530cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1531f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetI();
1532cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1533ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15341bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
15352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
153600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1537e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
1538cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1539ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15401bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
15412d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
154200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1543e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetI();
1544cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1545ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15461bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1547cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
154872025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
15492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
155025e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1551e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1552cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1553f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetJ();
1554cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1555ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15561bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
15572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
155800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1559e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
1560cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1561ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15621bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
15632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
156400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1565e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
1566cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1567ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15681bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1569cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
157072025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
15712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
157225e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1573e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1574cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1575f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetF();
1576cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1577ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15781bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
15792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
158000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1581e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
1582cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1583ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15841bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
15852d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
158600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1587e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetF();
1588cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1589ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
15901bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1591cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
159272025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
15932d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
159425e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1595e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1596cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1597f24d3cedd395690f6904aaac80f84a100420f7a3Elliott Hughes    return result.GetD();
1598cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1599ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
16001bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
16012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
160200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1603e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
1604cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1605ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
16061bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
16072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
160800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1609e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return InvokeWithJValues(soa, nullptr, mid, args).GetD();
1610cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1611ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
16121bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1613cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_list ap;
161472025e5f8f2743b4af33453df5b3bddada2078dbElliott Hughes    va_start(ap, mid);
16152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
161625e8b91db37d9eccc3eed254fe8a340b973d38faIan Rogers    ScopedObjectAccess soa(env);
1617e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    InvokeWithVarArgs(soa, nullptr, mid, ap);
1618cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    va_end(ap);
1619cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1620ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
16211bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
16222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
162300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1624e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    InvokeWithVarArgs(soa, nullptr, mid, args);
1625cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1626ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
16271bac54ffa933fbe9b92b62437577f2f4583eff1aElliott Hughes  static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
16282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
162900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1630e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    InvokeWithJValues(soa, nullptr, mid, args);
1631cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1632ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1633814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
16341d99e4549309d05007d041d058b1878de88e9585Ian Rogers    if (UNLIKELY(char_count < 0)) {
163568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
16361d99e4549309d05007d041d058b1878de88e9585Ian Rogers      return nullptr;
16371d99e4549309d05007d041d058b1878de88e9585Ian Rogers    }
16381d99e4549309d05007d041d058b1878de88e9585Ian Rogers    if (UNLIKELY(chars == nullptr && char_count > 0)) {
163968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
16401d99e4549309d05007d041d058b1878de88e9585Ian Rogers      return nullptr;
1641bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    }
164200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1643e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
164400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jstring>(result);
1645cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1646ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1647814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  static jstring NewStringUTF(JNIEnv* env, const char* utf) {
1648e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (utf == nullptr) {
1649e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      return nullptr;
1650814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes    }
165100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1652e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
165300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jstring>(result);
1654cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1655ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1656814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  static jsize GetStringLength(JNIEnv* env, jstring java_string) {
16572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
165800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1659e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return soa.Decode<mirror::String*>(java_string)->GetLength();
1660814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  }
1661814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1662814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
16632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
166400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1665e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
1666814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  }
1667814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes
1668bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1669bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                              jchar* buf) {
16702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
167100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1672e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* s = soa.Decode<mirror::String*>(java_string);
1673b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    if (start < 0 || length < 0 || start + length > s->GetLength()) {
167400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      ThrowSIOOBE(soa, start, length, s->GetLength());
1675b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    } else {
16763b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier      CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1677848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      const jchar* chars = s->GetValue();
1678b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      memcpy(buf, chars + start, length * sizeof(jchar));
1679b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    }
16808a26c5c4c74b09e2887593c733a22652a9f80d7cElliott Hughes  }
1681ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1682bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1683bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 char* buf) {
16842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
168500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1686e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* s = soa.Decode<mirror::String*>(java_string);
1687b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    if (start < 0 || length < 0 || start + length > s->GetLength()) {
168800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      ThrowSIOOBE(soa, start, length, s->GetLength());
1689b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    } else {
16903b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier      CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1691848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      const jchar* chars = s->GetValue();
1692b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      ConvertUtf16ToModifiedUtf8(buf, chars + start, length);
1693b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    }
1694cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1695ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
16967577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
16973b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_string);
169800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1699e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* s = soa.Decode<mirror::String*>(java_string);
170056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    gc::Heap* heap = Runtime::Current()->GetHeap();
1701848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    if (heap->IsMovableObject(s)) {
1702848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      jchar* chars = new jchar[s->GetLength()];
1703848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
170456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      if (is_copy != nullptr) {
170556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih        *is_copy = JNI_TRUE;
170656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      }
1707848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      return chars;
1708848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    }
1709848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    if (is_copy != nullptr) {
1710848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      *is_copy = JNI_FALSE;
17117577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    }
1712848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    return static_cast<jchar*>(s->GetValue());
1713cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1714ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1715590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
17162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
171700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
171856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    mirror::String* s = soa.Decode<mirror::String*>(java_string);
1719848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    if (chars != s->GetValue()) {
172056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      delete[] chars;
172156890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    }
1722cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1723ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17247577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
172556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    CHECK_NON_NULL_ARGUMENT(java_string);
172656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    ScopedObjectAccess soa(env);
172756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    mirror::String* s = soa.Decode<mirror::String*>(java_string);
172856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    gc::Heap* heap = Runtime::Current()->GetHeap();
1729848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    if (heap->IsMovableObject(s)) {
173056890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      StackHandleScope<1> hs(soa.Self());
1731848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao      HandleWrapper<mirror::String> h(hs.NewHandleWrapper(&s));
173256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      heap->IncrementDisableMovingGC(soa.Self());
173356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    }
173456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    if (is_copy != nullptr) {
173556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      *is_copy = JNI_FALSE;
173656890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    }
1737848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    return static_cast<jchar*>(s->GetValue());
1738cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1739ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17407577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) {
17416a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers    UNUSED(chars);
174256890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
174356890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    ScopedObjectAccess soa(env);
174456890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    gc::Heap* heap = Runtime::Current()->GetHeap();
174556890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    mirror::String* s = soa.Decode<mirror::String*>(java_string);
1746848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    if (heap->IsMovableObject(s)) {
174756890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih      heap->DecrementDisableMovingGC(soa.Self());
174856890e2615ab3dd612f1f81c3cadab6299eceacbFred Shih    }
1749cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1750ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
17517577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
1752e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (java_string == nullptr) {
1753e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      return nullptr;
17547577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    }
1755e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (is_copy != nullptr) {
17567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes      *is_copy = JNI_TRUE;
17577577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    }
1758ef28b14268ed0f9db0c7bbd571aa514354a360bdIan Rogers    ScopedObjectAccess soa(env);
1759e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::String* s = soa.Decode<mirror::String*>(java_string);
17607577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    size_t byte_count = s->GetUtfLength();
17617577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    char* bytes = new char[byte_count + 1];
1762e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    CHECK(bytes != nullptr);  // bionic aborts anyway.
1763848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao    const uint16_t* chars = s->GetValue();
17647577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength());
17657577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    bytes[byte_count] = '\0';
17667577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    return bytes;
1767b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  }
1768b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
17696a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers  static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
17707577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    delete[] chars;
1771b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  }
1772b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
1773bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes  static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
17742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
177500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1776e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
1777ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    if (UNLIKELY(!obj->IsArrayInstance())) {
177868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
177968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      return 0;
178096a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    }
1781e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Array* array = obj->AsArray();
1782bd9359912e5398799f60649b86ae80644ec72627Elliott Hughes    return array->GetLength();
1783cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1784ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1785814e40397fe6c8a2c645bae99f356dbddd6dbe18Elliott Hughes  static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
17863b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_array);
178700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1788e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ObjectArray<mirror::Object>* array =
1789e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
179000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobject>(array->Get(index));
1791cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1792d8ddfd5eadde1d5f53ef1419f529c799233eaa62Elliott Hughes
1793bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1794bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                    jobject java_value) {
17952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
179600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1797e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ObjectArray<mirror::Object>* array =
1798e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
1799e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
1800d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    array->Set<false>(index, value);
1801cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1802f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
1803cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
18042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
1805cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1806ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1807cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
18082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
1809cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1810ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1811cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jcharArray NewCharArray(JNIEnv* env, jsize length) {
18122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
1813cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1814ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1815cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
18162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
1817cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1818ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1819cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
18202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
1821cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1822ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1823cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jintArray NewIntArray(JNIEnv* env, jsize length) {
18242d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
1825cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1826ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1827cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jlongArray NewLongArray(JNIEnv* env, jsize length) {
18282d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
1829cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1830f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
18311d99e4549309d05007d041d058b1878de88e9585Ian Rogers  static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
18321d99e4549309d05007d041d058b1878de88e9585Ian Rogers                                     jobject initial_element) {
18331d99e4549309d05007d041d058b1878de88e9585Ian Rogers    if (UNLIKELY(length < 0)) {
183468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
18351d99e4549309d05007d041d058b1878de88e9585Ian Rogers      return nullptr;
183696a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    }
18372d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT(element_jclass);
1838cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
1839cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    // Compute the array class corresponding to the given element class.
1840ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom    ScopedObjectAccess soa(env);
1841e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* array_class;
18421d99e4549309d05007d041d058b1878de88e9585Ian Rogers    {
1843e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
18441d99e4549309d05007d041d058b1878de88e9585Ian Rogers      if (UNLIKELY(element_class->IsPrimitive())) {
184568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s",
184668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                            PrettyDescriptor(element_class).c_str());
18471d99e4549309d05007d041d058b1878de88e9585Ian Rogers        return nullptr;
18481d99e4549309d05007d041d058b1878de88e9585Ian Rogers      }
18491d99e4549309d05007d041d058b1878de88e9585Ian Rogers      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1850b74cd29802f364b4cec88f4913fa38ade26b8fabMathieu Chartier      array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
18511d99e4549309d05007d041d058b1878de88e9585Ian Rogers      if (UNLIKELY(array_class == nullptr)) {
18521d99e4549309d05007d041d058b1878de88e9585Ian Rogers        return nullptr;
18531d99e4549309d05007d041d058b1878de88e9585Ian Rogers      }
1854cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
1855cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes
18567577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    // Allocate and initialize if necessary.
1857e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::ObjectArray<mirror::Object>* result =
1858e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
18591d99e4549309d05007d041d058b1878de88e9585Ian Rogers    if (result != nullptr && initial_element != nullptr) {
1860e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
18611d99e4549309d05007d041d058b1878de88e9585Ian Rogers      if (initial_object != nullptr) {
18621d99e4549309d05007d041d058b1878de88e9585Ian Rogers        mirror::Class* element_class = result->GetClass()->GetComponentType();
18631d99e4549309d05007d041d058b1878de88e9585Ian Rogers        if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
186468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers          soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
186568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              "element type of '%s'",
186668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              PrettyDescriptor(initial_object->GetClass()).c_str(),
186768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                              PrettyDescriptor(element_class).c_str());
186868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers          return nullptr;
18691d99e4549309d05007d041d058b1878de88e9585Ian Rogers        } else {
18701d99e4549309d05007d041d058b1878de88e9585Ian Rogers          for (jsize i = 0; i < length; ++i) {
1871d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz            result->SetWithoutChecks<false>(i, initial_object);
18721d99e4549309d05007d041d058b1878de88e9585Ian Rogers          }
18731d99e4549309d05007d041d058b1878de88e9585Ian Rogers        }
18747577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes      }
18757577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes    }
187600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<jobjectArray>(result);
1877f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes  }
1878f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes
1879cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jshortArray NewShortArray(JNIEnv* env, jsize length) {
18802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
1881cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1882ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1883a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers  static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
18843b60fea8458f0bf65ef4530e1c4ee6fdd4b199e9Mathieu Chartier    CHECK_NON_NULL_ARGUMENT(java_array);
188500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
1886e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
18872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
188868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
188968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                          PrettyDescriptor(array->GetClass()).c_str());
18902d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return nullptr;
18912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
1892590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    gc::Heap* heap = Runtime::Current()->GetHeap();
1893590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    if (heap->IsMovableObject(array)) {
18941d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier      heap->IncrementDisableMovingGC(soa.Self());
1895590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
1896e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      array = soa.Decode<mirror::Array*>(java_array);
1897590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    }
1898590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    if (is_copy != nullptr) {
1899a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers      *is_copy = JNI_FALSE;
1900a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers    }
1901ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
1902b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  }
1903b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
19042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
19052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                            jint mode) {
19062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
19072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ScopedObjectAccess soa(env);
19082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
19092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
191068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
191168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                          PrettyDescriptor(array->GetClass()).c_str());
19122d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return;
19132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
19142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    const size_t component_size = array->GetClass()->GetComponentSize();
19152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray(soa, array, component_size, elements, mode);
1916b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  }
1917b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
19187577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
19192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
1920cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1921ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
19227577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
19232d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
1924cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1925ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
19267577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
19272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
1928cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1929ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
19307577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
19312d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
1932cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1933ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
19347577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
19352d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
1936cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1937ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
19387577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
19392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
1940cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1941ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
19427577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
19432d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
1944cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1945ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
19467577075b147fd8fa37ca41e7a32d1124676776ceElliott Hughes  static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
19472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
1948cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1949ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1950590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
1951590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                                          jint mode) {
19522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
19532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                                         mode);
1954cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1955ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1956590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
19572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
1958cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1959ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1960590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
19612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
1962cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1963ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1964590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
1965590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                                         jint mode) {
19662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
1967cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1968ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1969590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
1970590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                                        jint mode) {
19712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
1972cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1973ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1974590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
19752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
1976cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1977ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1978590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
19792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
1980cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1981ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1982590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
1983590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier                                        jint mode) {
19842d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
1985cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1986ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1987bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
1988bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                    jboolean* buf) {
19892d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
1990e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                                                           length, buf);
1991cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1992ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1993bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
1994bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 jbyte* buf) {
19952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
1996cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
1997ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
1998bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
1999bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 jchar* buf) {
20002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2001cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2002ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2003bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2004bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                   jdouble* buf) {
20052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2006e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                                                        buf);
2007cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2008ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2009bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2010bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                  jfloat* buf) {
20112d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2012e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                                                     buf);
2013cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2014ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2015bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2016bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                jint* buf) {
20172d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2018cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2019ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2020bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2021bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 jlong* buf) {
20222d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2023cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2024ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2025bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2026bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                  jshort* buf) {
20272d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2028e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                                                     buf);
2029cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2030ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2031bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2032bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                    const jboolean* buf) {
20332d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
2034491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                                                                           length, buf);
2035cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2036ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2037bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2038bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 const jbyte* buf) {
20392d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
2040cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2041ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2042bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2043bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 const jchar* buf) {
20442d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2045cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2046ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2047bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2048bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                   const jdouble* buf) {
20492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2050491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                                                                        buf);
2051cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2052ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2053bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2054bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                  const jfloat* buf) {
20552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2056491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom                                                                     buf);
2057cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2058ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2059bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2060bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                const jint* buf) {
20612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2062cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2063ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2064bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2065bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                 const jlong* buf) {
20662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2067cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2068ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2069bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2070bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                  const jshort* buf) {
20712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2072e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier                                                                     buf);
2073cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2074ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2075bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2076bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                              jint method_count) {
2077c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes    return RegisterNativeMethods(env, java_class, methods, method_count, true);
2078c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes  }
2079c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes
2080bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers  static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2081bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                                    jint method_count, bool return_errors) {
2082bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    if (UNLIKELY(method_count < 0)) {
208368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
208468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                       method_count);
208568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      return JNI_ERR;  // Not reached except in unit tests.
2086bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    }
20872d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
208800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2089e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
2090bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    if (UNLIKELY(method_count == 0)) {
2091bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers      LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2092bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers          << PrettyDescriptor(c);
2093bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers      return JNI_OK;
2094bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    }
20952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
2096bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers    for (jint i = 0; i < method_count; ++i) {
2097cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      const char* name = methods[i].name;
2098cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      const char* sig = methods[i].signature;
2099fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      const void* fnPtr = methods[i].fnPtr;
2100fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      if (UNLIKELY(name == nullptr)) {
2101fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2102fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        return JNI_ERR;
2103fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      } else if (UNLIKELY(sig == nullptr)) {
2104fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2105fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        return JNI_ERR;
2106fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      } else if (UNLIKELY(fnPtr == nullptr)) {
2107fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2108fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz        return JNI_ERR;
2109fa65e846362829d6e444bd88b12fe2496b3d5647Sebastien Hertz      }
21101eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers      bool is_fast = false;
2111368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // Notes about fast JNI calls:
2112368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      //
2113368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // On a normal JNI call, the calling thread usually transitions
2114368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // from the kRunnable state to the kNative state. But if the
2115368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // called native function needs to access any Java object, it
2116368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // will have to transition back to the kRunnable state.
2117368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      //
2118368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // There is a cost to this double transition. For a JNI call
2119368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // that should be quick, this cost may dominate the call cost.
2120368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      //
2121368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // On a fast JNI call, the calling thread avoids this double
2122368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // transition by not transitioning from kRunnable to kNative and
2123368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // stays in the kRunnable state.
2124368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      //
2125368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // There are risks to using a fast JNI call because it can delay
2126368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // a response to a thread suspension request which is typically
2127368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // used for a GC root scanning, etc. If a fast JNI call takes a
2128368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // long time, it could cause longer thread suspension latency
2129368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // and GC pauses.
2130368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      //
2131368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // Thus, fast JNI should be used with care. It should be used
2132368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // for a JNI call that takes a short amount of time (eg. no
2133368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // long-running loop) and does not block (eg. no locks, I/O,
2134368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // etc.)
2135368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      //
2136368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // A '!' prefix in the signature in the JNINativeMethod
2137368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // indicates that it's a fast JNI call and the runtime omits the
2138368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // thread state transition from kRunnable to kNative at the
2139368010a82f796f9716c62f7af339ea51785768aeHiroshi Yamauchi      // entry.
2140cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      if (*sig == '!') {
21411eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers        is_fast = true;
2142cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        ++sig;
2143cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      }
21440af5543f8ea20c3e655b2d748a1b7dcf283792feElliott Hughes
214582566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe      // Note: the right order is to try to find the method locally
214682566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe      // first, either as a direct or a virtual method. Then move to
214782566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe      // the parent.
21483d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier      ArtMethod* m = nullptr;
214982566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe      bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
215082566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe      for (mirror::Class* current_class = c;
215182566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe           current_class != nullptr;
215282566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe           current_class = current_class->GetSuperClass()) {
215382566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe        // Search first only comparing methods which are native.
215482566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe        m = FindMethod<true>(current_class, name, sig);
215582566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe        if (m != nullptr) {
215682566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe          break;
215782566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe        }
215882566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe
215982566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe        // Search again comparing to all methods, to find non-native methods that match.
216082566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe        m = FindMethod<false>(current_class, name, sig);
216182566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe        if (m != nullptr) {
216282566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe          break;
216382566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe        }
216482566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe
216582566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe        if (warn_on_going_to_parent) {
216682566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe          LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
216782566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe                       << "This is slow, consider changing your RegisterNatives calls.";
216882566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe          warn_on_going_to_parent = false;
216982566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe        }
2170cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      }
217182566091466b5b3f529168681ecfe3e739ef08b5Andreas Gampe
2172e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      if (m == nullptr) {
2173a6ce5b2d5ade23087ab15f26d4c487570ad84b5eMathieu Chartier        LOG(return_errors ? ERROR : INTERNAL_FATAL) << "Failed to register native method "
21740177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers            << PrettyDescriptor(c) << "." << name << sig << " in "
21750177e53ea521ad58b70c305700dab32f1ac773b7Ian Rogers            << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
2176a6ce5b2d5ade23087ab15f26d4c487570ad84b5eMathieu Chartier        // Safe to pass in LOG(FATAL) since the log object aborts in destructor and only goes
2177a6ce5b2d5ade23087ab15f26d4c487570ad84b5eMathieu Chartier        // out of scope after the DumpClass is done executing.
2178a6ce5b2d5ade23087ab15f26d4c487570ad84b5eMathieu Chartier        c->DumpClass(LOG(return_errors ? ERROR : FATAL), mirror::Class::kDumpClassFullDetail);
217900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
2180cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        return JNI_ERR;
21815174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes      } else if (!m->IsNative()) {
2182c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes        LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
2183bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            << PrettyDescriptor(c) << "." << name << sig
2184bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers            << " as native";
218500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers        ThrowNoSuchMethodError(soa, c, name, sig, "native");
2186cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes        return JNI_ERR;
2187cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes      }
21885174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
21894dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes      VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
21905174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
21916f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers      m->RegisterNative(fnPtr, is_fast);
21924dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers    }
2193cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    return JNI_OK;
21944dd71f1538a8d788c56c77378a59ce32afa519d7Ian Rogers  }
2195ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
21965174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes  static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
21972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
219800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2199e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
22005174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
22014dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
22025174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
22032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    size_t unregistered_count = 0;
22043d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
22053d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    for (auto& m : c->GetDirectMethods(pointer_size)) {
22063d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier      if (m.IsNative()) {
22073d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier        m.UnregisterNative();
22082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        unregistered_count++;
22095174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes      }
22105174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    }
22113d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier    for (auto& m : c->GetVirtualMethods(pointer_size)) {
22123d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier      if (m.IsNative()) {
22133d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier        m.UnregisterNative();
22142d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        unregistered_count++;
22155174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes      }
22165174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    }
22175174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes
22182d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (unregistered_count == 0) {
22192d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
22202d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers          << PrettyDescriptor(c) << "' that contains no native methods";
22212d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
22225174fe6e4e931c423e910366ff22ce0838567940Elliott Hughes    return JNI_OK;
2223cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2224ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2225719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers  static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
22262d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
222700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2228e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2229e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    o = o->MonitorEnter(soa.Self());
223000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (soa.Self()->IsExceptionPending()) {
2231ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes      return JNI_ERR;
2232ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes    }
223300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Env()->monitors.Add(o);
2234ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes    return JNI_OK;
2235cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2236ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2237719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers  static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
22382d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
223900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ScopedObjectAccess soa(env);
2240e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
224100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    o->MonitorExit(soa.Self());
224200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (soa.Self()->IsExceptionPending()) {
2243ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes      return JNI_ERR;
2244ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes    }
224500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    soa.Env()->monitors.Remove(o);
2246ab7b9dcbfc4264a0bc4889c3e463ff88a67f6a30Elliott Hughes    return JNI_OK;
2247f2682d5a6ce0f7de58da8fd4ec8aec200c43b92eElliott Hughes  }
2248ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2249cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
22502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
2251cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    Runtime* runtime = Runtime::Current();
2252e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (runtime != nullptr) {
225369f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes      *vm = runtime->GetJavaVM();
2254cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    } else {
2255e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier      *vm = nullptr;
2256cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes    }
2257e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return (*vm != nullptr) ? JNI_OK : JNI_ERR;
2258cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2259ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2260b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
226196a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    if (capacity < 0) {
226268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
226368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                       capacity);
226445d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom      return nullptr;
226596a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    }
2266e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    if (address == nullptr && capacity != 0) {
226768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
226868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                       "non-zero capacity for nullptr pointer: %" PRId64, capacity);
226945d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom      return nullptr;
227096a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    }
2271ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
227285a93364e5111dc56a73eed0130856e66cab0802Brian Carlstrom    // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
227345d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    if (capacity > INT_MAX) {
227468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
227568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                       "buffer capacity greater than maximum jint: %" PRId64,
227668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                       capacity);
227745d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom      return nullptr;
227845d26c86b00580593067ca42091ad66cf7dc4f7cBrian Carlstrom    }
2279b56812165dd3a2e6eb8b85c810943b3d7bd9bfc4Elliott Hughes    jlong address_arg = reinterpret_cast<jlong>(address);
2280b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    jint capacity_arg = static_cast<jint>(capacity);
2281ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2282aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes    jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2283aecb5f3fd5dcd78bc3e74993acc40fed815b6b8bElliott Hughes                                    WellKnownClasses::java_nio_DirectByteBuffer_init,
2284eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes                                    address_arg, capacity_arg);
2285e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
2286cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2287ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2288b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
2289e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return reinterpret_cast<void*>(env->GetLongField(
2290e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
2291cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2292ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2293b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
2294e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier    return static_cast<jlong>(env->GetIntField(
2295e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier        java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
2296cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
2297ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
2298a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe  static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2299a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe    if (java_object == nullptr) {
2300a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe      return JNIInvalidRefType;
2301a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe    }
2302b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
2303b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    // Do we definitely know what kind of reference this is?
2304b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2305b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    IndirectRefKind kind = GetIndirectRefKind(ref);
2306b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    switch (kind) {
2307c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers    case kLocal:
2308c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      return JNILocalRefType;
2309b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    case kGlobal:
2310b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      return JNIGlobalRefType;
2311b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    case kWeakGlobal:
2312b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes      return JNIWeakGlobalRefType;
2313eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    case kHandleScopeOrInvalid:
2314c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      // Assume value is in a handle scope.
2315c0542af3e2170143ba40d89136e284997e16bf64Ian Rogers      return JNILocalRefType;
2316b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    }
23172e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom    LOG(FATAL) << "IndirectRefKind[" << kind << "]";
2318a87630724ef4f8760684fa69c8ecc685735aff88Andreas Gampe    UNREACHABLE();
2319cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  }
232000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
232100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers private:
232268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
232368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                                          const char* caller)
232468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
232500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // TODO: we should try to expand the table if necessary.
2326aa836f7fa2ef359cf8ec1ef98d924f7971ba8352Elliott Hughes    if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
232700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
232800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return JNI_ERR;
232900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
233000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    // TODO: this isn't quite right, since "capacity" includes holes.
233135aef2ce9d9cbfb37e9b2f6776afce3caed37063Yevgeny Rouban    const size_t capacity = soa.Env()->locals.Capacity();
233200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
233300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (!okay) {
233400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      soa.Self()->ThrowOutOfMemoryError(caller);
233500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
233600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return okay ? JNI_OK : JNI_ERR;
233700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
233800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
233900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  template<typename JniT, typename ArtT>
23402d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
234168d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers    ScopedObjectAccess soa(env);
23421d99e4549309d05007d041d058b1878de88e9585Ian Rogers    if (UNLIKELY(length < 0)) {
234368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
23441d99e4549309d05007d041d058b1878de88e9585Ian Rogers      return nullptr;
234596a9887f0bc912661e0a7478c7eb19847d2e2e06Elliott Hughes    }
234650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers    ArtT* result = ArtT::Alloc(soa.Self(), length);
234700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return soa.AddLocalReference<JniT>(result);
234800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
234900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
23502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  template <typename JArrayT, typename ElementT, typename ArtArrayT>
23512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
23522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                           const char* fn_name, const char* operation)
2353b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
235400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
23552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
235668d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers      soa.Vm()->JniAbortF(fn_name,
235768d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                          "attempt to %s %s primitive array elements with an object of type %s",
235868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                          operation,
235968d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                          PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
236068d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                          PrettyDescriptor(array->GetClass()).c_str());
23612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return nullptr;
23622d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
23632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
23642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return array;
23652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
23662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
23672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  template <typename ArrayT, typename ElementT, typename ArtArrayT>
23682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
23692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT(java_array);
23702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ScopedObjectAccess soa(env);
23712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
23722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                                            "GetArrayElements",
23732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                                            "get");
23742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (UNLIKELY(array == nullptr)) {
23752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return nullptr;
23762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
2377590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    // Only make a copy if necessary.
2378590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2379590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      if (is_copy != nullptr) {
2380590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        *is_copy = JNI_TRUE;
2381590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      }
23822d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      const size_t component_size = sizeof(ElementT);
2383590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      size_t size = array->GetLength() * component_size;
2384590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      void* data = new uint64_t[RoundUp(size, 8) / 8];
2385590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      memcpy(data, array->GetData(), size);
23862d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return reinterpret_cast<ElementT*>(data);
2387590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    } else {
2388590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      if (is_copy != nullptr) {
2389590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        *is_copy = JNI_FALSE;
2390590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      }
23912d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return reinterpret_cast<ElementT*>(array->GetData());
239200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
239300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
239400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
23952d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  template <typename ArrayT, typename ElementT, typename ArtArrayT>
2396590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
23972d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2398590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    ScopedObjectAccess soa(env);
23992d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
24002d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                                            "ReleaseArrayElements",
24012d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                                            "release");
24022d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (array == nullptr) {
24032d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      return;
24042d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    }
24052d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
24062d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
24072d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
24082d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
24092d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                    size_t component_size, void* elements, jint mode)
24102d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2411ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    void* array_data = array->GetRawData(component_size, 0);
2412590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    gc::Heap* heap = Runtime::Current()->GetHeap();
24132d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    bool is_copy = array_data != elements;
2414590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    size_t bytes = array->GetLength() * component_size;
24152d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    VLOG(heap) << "Release primitive array " << soa.Env() << " array_data " << array_data
24162d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers               << " elements " << elements;
2417d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier    if (is_copy) {
2418d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier      // Sanity check: If elements is not the same as the java array's data, it better not be a
2419d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier      // heap address. TODO: This might be slow to check, may be worth keeping track of which
2420d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier      // copies we make?
2421d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier      if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
242268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers        soa.Vm()->JniAbortF("ReleaseArrayElements",
242368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                            "invalid element pointer %p, array elements are %p",
242468d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers                            reinterpret_cast<void*>(elements), array_data);
2425d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier        return;
2426d68ac700820f3e4253c8b4bcf718daf452f6da4cMathieu Chartier      }
242724555ad5150e6ed31609a1f3c8c1a7e28a939301Mathieu Chartier      if (mode != JNI_ABORT) {
242824555ad5150e6ed31609a1f3c8c1a7e28a939301Mathieu Chartier        memcpy(array_data, elements, bytes);
242924555ad5150e6ed31609a1f3c8c1a7e28a939301Mathieu Chartier      } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
243024555ad5150e6ed31609a1f3c8c1a7e28a939301Mathieu Chartier        // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
243124555ad5150e6ed31609a1f3c8c1a7e28a939301Mathieu Chartier        LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
243224555ad5150e6ed31609a1f3c8c1a7e28a939301Mathieu Chartier        soa.Self()->DumpJavaStack(LOG(WARNING));
243324555ad5150e6ed31609a1f3c8c1a7e28a939301Mathieu Chartier      }
2434590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    }
243500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (mode != JNI_COMMIT) {
2436590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      if (is_copy) {
2437590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier        delete[] reinterpret_cast<uint64_t*>(elements);
24383e8b2e1f14176c6beb61a31a27af30bc35998e80Mathieu Chartier      } else if (heap->IsMovableObject(array)) {
24391d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier        // Non copy to a movable object must means that we had disabled the moving GC.
24401d27b34d3b18a5a0c832dae9768366dc08ef8d1cMathieu Chartier        heap->DecrementDisableMovingGC(soa.Self());
2441590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier      }
244200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
244300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
244400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
24452d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  template <typename JArrayT, typename ElementT, typename ArtArrayT>
24462d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
24472d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                      jsize start, jsize length, ElementT* buf) {
24482d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
24492d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ScopedObjectAccess soa(env);
24502d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ArtArrayT* array =
24512d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
24522d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                              "GetPrimitiveArrayRegion",
24532d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                              "get region of");
24542d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (array != nullptr) {
24552d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      if (start < 0 || length < 0 || start + length > array->GetLength()) {
24562d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        ThrowAIOOBE(soa, array, start, length, "src");
24572d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      } else {
24582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
24592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        ElementT* data = array->GetData();
24602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        memcpy(buf, data + start, length * sizeof(ElementT));
24612d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      }
246200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
246300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
246400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
24652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  template <typename JArrayT, typename ElementT, typename ArtArrayT>
24662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
24672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                      jsize start, jsize length, const ElementT* buf) {
24682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
24692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ScopedObjectAccess soa(env);
24702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    ArtArrayT* array =
24712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
24722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                              "SetPrimitiveArrayRegion",
24732d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers                                                              "set region of");
24742d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    if (array != nullptr) {
24752d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      if (start < 0 || length < 0 || start + length > array->GetLength()) {
24762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        ThrowAIOOBE(soa, array, start, length, "dst");
24772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      } else {
24782d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
24792d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        ElementT* data = array->GetData();
24802d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers        memcpy(data + start, buf, length * sizeof(ElementT));
24812d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers      }
248200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    }
248300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
2484cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes};
2485ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
248688c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughesconst JNINativeInterface gJniNativeInterface = {
2487e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  nullptr,  // reserved0.
2488e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  nullptr,  // reserved1.
2489e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  nullptr,  // reserved2.
2490e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  nullptr,  // reserved3.
2491cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetVersion,
2492cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::DefineClass,
2493cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::FindClass,
2494cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::FromReflectedMethod,
2495cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::FromReflectedField,
2496cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ToReflectedMethod,
2497cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetSuperclass,
2498cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::IsAssignableFrom,
2499cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ToReflectedField,
2500cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::Throw,
2501cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ThrowNew,
2502cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ExceptionOccurred,
2503cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ExceptionDescribe,
2504cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ExceptionClear,
2505cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::FatalError,
2506cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::PushLocalFrame,
2507cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::PopLocalFrame,
2508cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewGlobalRef,
2509cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::DeleteGlobalRef,
2510cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::DeleteLocalRef,
2511cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::IsSameObject,
2512cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewLocalRef,
2513cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::EnsureLocalCapacity,
2514cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::AllocObject,
2515cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewObject,
2516cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewObjectV,
2517cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewObjectA,
2518cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetObjectClass,
2519cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::IsInstanceOf,
2520cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetMethodID,
2521cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallObjectMethod,
2522cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallObjectMethodV,
2523cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallObjectMethodA,
2524cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallBooleanMethod,
2525cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallBooleanMethodV,
2526cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallBooleanMethodA,
2527cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallByteMethod,
2528cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallByteMethodV,
2529cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallByteMethodA,
2530cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallCharMethod,
2531cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallCharMethodV,
2532cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallCharMethodA,
2533cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallShortMethod,
2534cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallShortMethodV,
2535cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallShortMethodA,
2536cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallIntMethod,
2537cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallIntMethodV,
2538cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallIntMethodA,
2539cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallLongMethod,
2540cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallLongMethodV,
2541cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallLongMethodA,
2542cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallFloatMethod,
2543cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallFloatMethodV,
2544cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallFloatMethodA,
2545cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallDoubleMethod,
2546cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallDoubleMethodV,
2547cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallDoubleMethodA,
2548cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallVoidMethod,
2549cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallVoidMethodV,
2550cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallVoidMethodA,
2551cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualObjectMethod,
2552cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualObjectMethodV,
2553cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualObjectMethodA,
2554cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualBooleanMethod,
2555cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualBooleanMethodV,
2556cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualBooleanMethodA,
2557cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualByteMethod,
2558cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualByteMethodV,
2559cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualByteMethodA,
2560cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualCharMethod,
2561cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualCharMethodV,
2562cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualCharMethodA,
2563cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualShortMethod,
2564cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualShortMethodV,
2565cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualShortMethodA,
2566cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualIntMethod,
2567cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualIntMethodV,
2568cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualIntMethodA,
2569cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualLongMethod,
2570cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualLongMethodV,
2571cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualLongMethodA,
2572cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualFloatMethod,
2573cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualFloatMethodV,
2574cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualFloatMethodA,
2575cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualDoubleMethod,
2576cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualDoubleMethodV,
2577cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualDoubleMethodA,
2578cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualVoidMethod,
2579cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualVoidMethodV,
2580cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallNonvirtualVoidMethodA,
2581cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetFieldID,
2582cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetObjectField,
2583cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetBooleanField,
2584cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetByteField,
2585cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetCharField,
2586cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetShortField,
2587cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetIntField,
2588cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetLongField,
2589cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetFloatField,
2590cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetDoubleField,
2591cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetObjectField,
2592cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetBooleanField,
2593cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetByteField,
2594cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetCharField,
2595cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetShortField,
2596cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetIntField,
2597cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetLongField,
2598cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetFloatField,
2599cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetDoubleField,
2600cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticMethodID,
2601cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticObjectMethod,
2602cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticObjectMethodV,
2603cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticObjectMethodA,
2604cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticBooleanMethod,
2605cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticBooleanMethodV,
2606cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticBooleanMethodA,
2607cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticByteMethod,
2608cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticByteMethodV,
2609cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticByteMethodA,
2610cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticCharMethod,
2611cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticCharMethodV,
2612cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticCharMethodA,
2613cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticShortMethod,
2614cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticShortMethodV,
2615cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticShortMethodA,
2616cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticIntMethod,
2617cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticIntMethodV,
2618cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticIntMethodA,
2619cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticLongMethod,
2620cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticLongMethodV,
2621cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticLongMethodA,
2622cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticFloatMethod,
2623cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticFloatMethodV,
2624cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticFloatMethodA,
2625cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticDoubleMethod,
2626cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticDoubleMethodV,
2627cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticDoubleMethodA,
2628cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticVoidMethod,
2629cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticVoidMethodV,
2630cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::CallStaticVoidMethodA,
2631cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticFieldID,
2632cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticObjectField,
2633cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticBooleanField,
2634cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticByteField,
2635cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticCharField,
2636cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticShortField,
2637cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticIntField,
2638cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticLongField,
2639cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticFloatField,
2640cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStaticDoubleField,
2641cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticObjectField,
2642cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticBooleanField,
2643cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticByteField,
2644cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticCharField,
2645cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticShortField,
2646cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticIntField,
2647cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticLongField,
2648cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticFloatField,
2649cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetStaticDoubleField,
2650cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewString,
2651cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringLength,
2652cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringChars,
2653cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseStringChars,
2654cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewStringUTF,
2655cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringUTFLength,
2656cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringUTFChars,
2657cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseStringUTFChars,
2658cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetArrayLength,
2659cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewObjectArray,
2660cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetObjectArrayElement,
2661cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetObjectArrayElement,
2662cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewBooleanArray,
2663cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewByteArray,
2664cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewCharArray,
2665cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewShortArray,
2666cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewIntArray,
2667cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewLongArray,
2668cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewFloatArray,
2669cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewDoubleArray,
2670cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetBooleanArrayElements,
2671cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetByteArrayElements,
2672cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetCharArrayElements,
2673cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetShortArrayElements,
2674cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetIntArrayElements,
2675cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetLongArrayElements,
2676cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetFloatArrayElements,
2677cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetDoubleArrayElements,
2678cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseBooleanArrayElements,
2679cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseByteArrayElements,
2680cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseCharArrayElements,
2681cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseShortArrayElements,
2682cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseIntArrayElements,
2683cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseLongArrayElements,
2684cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseFloatArrayElements,
2685cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseDoubleArrayElements,
2686cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetBooleanArrayRegion,
2687cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetByteArrayRegion,
2688cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetCharArrayRegion,
2689cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetShortArrayRegion,
2690cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetIntArrayRegion,
2691cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetLongArrayRegion,
2692cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetFloatArrayRegion,
2693cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetDoubleArrayRegion,
2694cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetBooleanArrayRegion,
2695cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetByteArrayRegion,
2696cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetCharArrayRegion,
2697cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetShortArrayRegion,
2698cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetIntArrayRegion,
2699cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetLongArrayRegion,
2700cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetFloatArrayRegion,
2701cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::SetDoubleArrayRegion,
2702cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::RegisterNatives,
2703cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::UnregisterNatives,
2704cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::MonitorEnter,
2705cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::MonitorExit,
2706cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetJavaVM,
2707cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringRegion,
2708cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringUTFRegion,
2709cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetPrimitiveArrayCritical,
2710cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleasePrimitiveArrayCritical,
2711cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetStringCritical,
2712cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ReleaseStringCritical,
2713cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewWeakGlobalRef,
2714cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::DeleteWeakGlobalRef,
2715cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::ExceptionCheck,
2716cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::NewDirectByteBuffer,
2717cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetDirectBufferAddress,
2718cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetDirectBufferCapacity,
2719cdf53120cd5a73cbedc1654e22542848468c0d2fElliott Hughes  JNI::GetObjectRefType,
2720ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro};
2721ea4dca856f8c19299a1858d2cc1f35b03ca0f694Carl Shapiro
272268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogersconst JNINativeInterface* GetJniNativeInterface() {
272368d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers  return &gJniNativeInterface;
2724410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes}
2725410c0c876f326e14c176a39ba21fc4dd3f7db8abElliott Hughes
2726c8fece309fa1d3514071fadaca34530648462b50Elliott Hughesvoid RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
2727bc939663ccfbe0c648dd6a3670041510aca82420Ian Rogers                           jint method_count) {
2728c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes  ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
2729e7e8a5fea2d852cccc840fa046151a16627f26cdMathieu Chartier  if (c.get() == nullptr) {
2730c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes    LOG(FATAL) << "Couldn't find class: " << jni_class_name;
2731c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes  }
2732c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes  JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
2733c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes}
2734c8fece309fa1d3514071fadaca34530648462b50Elliott Hughes
2735df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers}  // namespace art
2736b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes
2737b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
2738b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  switch (rhs) {
2739b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  case JNIInvalidRefType:
2740b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    os << "JNIInvalidRefType";
2741b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    return os;
2742b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  case JNILocalRefType:
2743b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    os << "JNILocalRefType";
2744b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    return os;
2745b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  case JNIGlobalRefType:
2746b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    os << "JNIGlobalRefType";
2747b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    return os;
2748b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  case JNIWeakGlobalRefType:
2749b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    os << "JNIWeakGlobalRefType";
2750b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes    return os;
27512e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom  default:
2752c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers    LOG(::art::FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
2753c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers    UNREACHABLE();
2754b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes  }
2755b465ab0e103d7760df903c1fddf4fa6b89d5d1f5Elliott Hughes}
2756