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