17ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes/* 27ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * Copyright (C) 2008 The Android Open Source Project 37ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * 47ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 57ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * you may not use this file except in compliance with the License. 67ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * You may obtain a copy of the License at 77ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * 87ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 97ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * 107ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * Unless required by applicable law or agreed to in writing, software 117ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 127ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * See the License for the specific language governing permissions and 147ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes * limitations under the License. 157ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes */ 167ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 17277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe#include "dalvik_system_VMRuntime.h" 18277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe 19c60e1b755c5632dfeb04c333489ede52ee5c945fAndreas Gampe#ifdef __ANDROID__ 2015efde2badd80b8b124f8e1444165e4afbac17f0Dmitriy Ivanovextern "C" void android_set_application_target_sdk_version(uint32_t version); 2115efde2badd80b8b124f8e1444165e4afbac17f0Dmitriy Ivanov#endif 22eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes#include <limits.h> 23d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include <ScopedUtfChars.h> 24eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes 25d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#pragma GCC diagnostic push 26d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#pragma GCC diagnostic ignored "-Wshadow" 27d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "toStringArray.h" 28d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#pragma GCC diagnostic pop 29d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers 30e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method-inl.h" 31d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "arch/instruction_set.h" 329837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers#include "class_linker-inl.h" 3362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "common_throws.h" 34f6a1e1e44b94221c4e6b063b36921c712a33910bElliott Hughes#include "debugger.h" 354f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 36e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom#include "gc/accounting/card_table-inl.h" 371d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/allocator/dlmalloc.h" 3882353313bbe00d033b6733535d0dcd6f56c36d8dMathieu Chartier#include "gc/heap.h" 391d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/space/dlmalloc_space.h" 4031d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom#include "gc/space/image_space.h" 41a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier#include "gc/task_processor.h" 42e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom#include "intern_table.h" 437ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes#include "jni_internal.h" 444f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "mirror/class-inl.h" 45e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom#include "mirror/dex_cache-inl.h" 462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h" 47893263b7d5bc2ca43a91ecb8071867f5134fc60aMathieu Chartier#include "runtime.h" 481eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers#include "scoped_fast_native_object_access.h" 4900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 507ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes#include "thread.h" 5188c5c355fc3d881f905564911d746b2313d5fc89Elliott Hughes#include "thread_list.h" 52277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe 537ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughesnamespace art { 547ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 550512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jfloat VMRuntime_getTargetHeapUtilization(JNIEnv*, jobject) { 56b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes return Runtime::Current()->GetHeap()->GetTargetHeapUtilization(); 577ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 587ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 590512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMRuntime_nativeSetTargetHeapUtilization(JNIEnv*, jobject, jfloat target) { 60b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes Runtime::Current()->GetHeap()->SetTargetHeapUtilization(target); 617ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 627ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 630512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMRuntime_startJitCompilation(JNIEnv*, jobject) { 647ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 657ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 660512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMRuntime_disableJitCompilation(JNIEnv*, jobject) { 677ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 687ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 69590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierstatic jobject VMRuntime_newNonMovableArray(JNIEnv* env, jobject, jclass javaElementClass, 70e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom jint length) { 711eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers ScopedFastNativeObjectAccess soa(env); 72f9c612f2e657adb0764285256b228622e0789254Ian Rogers if (UNLIKELY(length < 0)) { 73f9c612f2e657adb0764285256b228622e0789254Ian Rogers ThrowNegativeArraySizeException(length); 74f9c612f2e657adb0764285256b228622e0789254Ian Rogers return nullptr; 75f9c612f2e657adb0764285256b228622e0789254Ian Rogers } 762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* element_class = soa.Decode<mirror::Class*>(javaElementClass); 779837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers if (UNLIKELY(element_class == nullptr)) { 780aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowNullPointerException("element class == null"); 799837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers return nullptr; 807ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes } 819837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers Runtime* runtime = Runtime::Current(); 82b74cd29802f364b4cec88f4913fa38ade26b8fabMathieu Chartier mirror::Class* array_class = 83b74cd29802f364b4cec88f4913fa38ade26b8fabMathieu Chartier runtime->GetClassLinker()->FindArrayClass(soa.Self(), &element_class); 849837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers if (UNLIKELY(array_class == nullptr)) { 859837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers return nullptr; 869837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers } 879837939678bb5dcba178e5fb00ed59b5d14c8d9bIan Rogers gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentNonMovingAllocator(); 88cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier mirror::Array* result = mirror::Array::Alloc<true>(soa.Self(), array_class, length, 89f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi array_class->GetComponentSizeShift(), 90f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi allocator); 9100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return soa.AddLocalReference<jobject>(result); 927ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 937ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 94f9c612f2e657adb0764285256b228622e0789254Ian Rogersstatic jobject VMRuntime_newUnpaddedArray(JNIEnv* env, jobject, jclass javaElementClass, 95f9c612f2e657adb0764285256b228622e0789254Ian Rogers jint length) { 96f9c612f2e657adb0764285256b228622e0789254Ian Rogers ScopedFastNativeObjectAccess soa(env); 97f9c612f2e657adb0764285256b228622e0789254Ian Rogers if (UNLIKELY(length < 0)) { 98f9c612f2e657adb0764285256b228622e0789254Ian Rogers ThrowNegativeArraySizeException(length); 99f9c612f2e657adb0764285256b228622e0789254Ian Rogers return nullptr; 100f9c612f2e657adb0764285256b228622e0789254Ian Rogers } 101f9c612f2e657adb0764285256b228622e0789254Ian Rogers mirror::Class* element_class = soa.Decode<mirror::Class*>(javaElementClass); 102f9c612f2e657adb0764285256b228622e0789254Ian Rogers if (UNLIKELY(element_class == nullptr)) { 1030aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowNullPointerException("element class == null"); 104f9c612f2e657adb0764285256b228622e0789254Ian Rogers return nullptr; 105f9c612f2e657adb0764285256b228622e0789254Ian Rogers } 106f9c612f2e657adb0764285256b228622e0789254Ian Rogers Runtime* runtime = Runtime::Current(); 10731d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(soa.Self(), 10831d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom &element_class); 109f9c612f2e657adb0764285256b228622e0789254Ian Rogers if (UNLIKELY(array_class == nullptr)) { 110f9c612f2e657adb0764285256b228622e0789254Ian Rogers return nullptr; 111f9c612f2e657adb0764285256b228622e0789254Ian Rogers } 112f9c612f2e657adb0764285256b228622e0789254Ian Rogers gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator(); 113f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi mirror::Array* result = mirror::Array::Alloc<true, true>(soa.Self(), array_class, length, 114f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi array_class->GetComponentSizeShift(), 115f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi allocator); 116f9c612f2e657adb0764285256b228622e0789254Ian Rogers return soa.AddLocalReference<jobject>(result); 117f9c612f2e657adb0764285256b228622e0789254Ian Rogers} 118f9c612f2e657adb0764285256b228622e0789254Ian Rogers 1190512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jlong VMRuntime_addressOf(JNIEnv* env, jobject, jobject javaArray) { 1202cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (javaArray == nullptr) { // Most likely allocation failed 121a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers return 0; 122a15e67d5ee5aa9615596cee2be42c2b2caf128c6Ian Rogers } 1231eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers ScopedFastNativeObjectAccess soa(env); 1242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Array* array = soa.Decode<mirror::Array*>(javaArray); 1257ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes if (!array->IsArrayInstance()) { 1260aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray ThrowIllegalArgumentException("not an array"); 1277ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes return 0; 1287ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes } 129590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (Runtime::Current()->GetHeap()->IsMovableObject(array)) { 130590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ThrowRuntimeException("Trying to get address of movable array object"); 131590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier return 0; 132590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier } 133ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return reinterpret_cast<uintptr_t>(array->GetRawData(array->GetClass()->GetComponentSize(), 0)); 1347ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 1357ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 1360512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic void VMRuntime_clearGrowthLimit(JNIEnv*, jobject) { 137b3bd5f07884f5a1f2b84224363b1372d7c28d447Elliott Hughes Runtime::Current()->GetHeap()->ClearGrowthLimit(); 1387ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 1397ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 140379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartierstatic void VMRuntime_clampGrowthLimit(JNIEnv*, jobject) { 141379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier Runtime::Current()->GetHeap()->ClampGrowthLimit(); 142379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier} 143379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier 1440512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jboolean VMRuntime_isDebuggerActive(JNIEnv*, jobject) { 145c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes return Dbg::IsDebuggerActive(); 1467ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 1477ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 148dfbbeef151d52ec9c5bbc9f12449d4c74b8ec19eOleksiy Vyalovstatic jboolean VMRuntime_isNativeDebuggable(JNIEnv*, jobject) { 149dfbbeef151d52ec9c5bbc9f12449d4c74b8ec19eOleksiy Vyalov return Runtime::Current()->IsNativeDebuggable(); 150dfbbeef151d52ec9c5bbc9f12449d4c74b8ec19eOleksiy Vyalov} 151dfbbeef151d52ec9c5bbc9f12449d4c74b8ec19eOleksiy Vyalov 1520512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jobjectArray VMRuntime_properties(JNIEnv* env, jobject) { 1537ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes return toStringArray(env, Runtime::Current()->GetProperties()); 1547ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 1557ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 1567d5ffb5ef4702e7a032db8a75783f1bac2ce04c9Brian Carlstrom// This is for backward compatibility with dalvik which returned the 1577d5ffb5ef4702e7a032db8a75783f1bac2ce04c9Brian Carlstrom// meaningless "." when no boot classpath or classpath was 1587d5ffb5ef4702e7a032db8a75783f1bac2ce04c9Brian Carlstrom// specified. Unfortunately, some tests were using java.class.path to 1597d5ffb5ef4702e7a032db8a75783f1bac2ce04c9Brian Carlstrom// lookup relative file locations, so they are counting on this to be 1607d5ffb5ef4702e7a032db8a75783f1bac2ce04c9Brian Carlstrom// ".", presumably some applications or libraries could have as well. 1610512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic const char* DefaultToDot(const std::string& class_path) { 1627d5ffb5ef4702e7a032db8a75783f1bac2ce04c9Brian Carlstrom return class_path.empty() ? "." : class_path.c_str(); 1637d5ffb5ef4702e7a032db8a75783f1bac2ce04c9Brian Carlstrom} 1647d5ffb5ef4702e7a032db8a75783f1bac2ce04c9Brian Carlstrom 1650512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jstring VMRuntime_bootClassPath(JNIEnv* env, jobject) { 166a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom return env->NewStringUTF(DefaultToDot(Runtime::Current()->GetBootClassPathString())); 1677ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 1687ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 1690512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jstring VMRuntime_classPath(JNIEnv* env, jobject) { 170a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom return env->NewStringUTF(DefaultToDot(Runtime::Current()->GetClassPathString())); 1717ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 1727ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 1730512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic jstring VMRuntime_vmVersion(JNIEnv* env, jobject) { 174491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom return env->NewStringUTF(Runtime::GetVersion()); 1757ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 1767ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 177cef450c613d8324db7c418130596182b8e9a5cddBrian Carlstromstatic jstring VMRuntime_vmLibrary(JNIEnv* env, jobject) { 178cef450c613d8324db7c418130596182b8e9a5cddBrian Carlstrom return env->NewStringUTF(kIsDebugBuild ? "libartd.so" : "libart.so"); 179cef450c613d8324db7c418130596182b8e9a5cddBrian Carlstrom} 180cef450c613d8324db7c418130596182b8e9a5cddBrian Carlstrom 181a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertzstatic jstring VMRuntime_vmInstructionSet(JNIEnv* env, jobject) { 182a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz InstructionSet isa = Runtime::Current()->GetInstructionSet(); 183a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz const char* isa_string = GetInstructionSetString(isa); 184a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz return env->NewStringUTF(isa_string); 185a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz} 186a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz 1876a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersstatic jboolean VMRuntime_is64Bit(JNIEnv*, jobject) { 188a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz bool is64BitMode = (sizeof(void*) == sizeof(uint64_t)); 189a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz return is64BitMode ? JNI_TRUE : JNI_FALSE; 190a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz} 191a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz 192a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertzstatic jboolean VMRuntime_isCheckJniEnabled(JNIEnv* env, jobject) { 1936a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled() ? JNI_TRUE : JNI_FALSE; 194a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz} 195a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz 196f00571c4e1ae202b3b4acb6b47cbe23a65178f7fJeff Haostatic void VMRuntime_setTargetSdkVersionNative(JNIEnv*, jobject, jint target_sdk_version) { 197987560fee798e48fb725c44b796d8ca7a5872ad6Ian Rogers // This is the target SDK version of the app we're about to run. It is intended that this a place 198987560fee798e48fb725c44b796d8ca7a5872ad6Ian Rogers // where workarounds can be enabled. 199c2dc62d1c9241dfe880a81698713c314b13aa63fElliott Hughes // Note that targetSdkVersion may be CUR_DEVELOPMENT (10000). 200c2dc62d1c9241dfe880a81698713c314b13aa63fElliott Hughes // Note that targetSdkVersion may be 0, meaning "current". 201f00571c4e1ae202b3b4acb6b47cbe23a65178f7fJeff Hao Runtime::Current()->SetTargetSdkVersion(target_sdk_version); 20215efde2badd80b8b124f8e1444165e4afbac17f0Dmitriy Ivanov 203c60e1b755c5632dfeb04c333489ede52ee5c945fAndreas Gampe#ifdef __ANDROID__ 20415efde2badd80b8b124f8e1444165e4afbac17f0Dmitriy Ivanov // This part is letting libc/dynamic linker know about current app's 20515efde2badd80b8b124f8e1444165e4afbac17f0Dmitriy Ivanov // target sdk version to enable compatibility workarounds. 20615efde2badd80b8b124f8e1444165e4afbac17f0Dmitriy Ivanov android_set_application_target_sdk_version(static_cast<uint32_t>(target_sdk_version)); 20715efde2badd80b8b124f8e1444165e4afbac17f0Dmitriy Ivanov#endif 2087ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 2097ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 210987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartierstatic void VMRuntime_registerNativeAllocation(JNIEnv* env, jobject, jint bytes) { 2111eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers if (UNLIKELY(bytes < 0)) { 2121eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers ScopedObjectAccess soa(env); 213987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier ThrowRuntimeException("allocation size negative %d", bytes); 214987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier return; 215987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier } 2168ec31f9835a8d1513be9be7f9fa236fe4715750dMathieu Chartier Runtime::Current()->GetHeap()->RegisterNativeAllocation(env, static_cast<size_t>(bytes)); 217987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier} 218987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier 2198fff24953c78bd58f3a42ac83b340b90e7e7228aCalin Juravlestatic void VMRuntime_registerSensitiveThread(JNIEnv*, jobject) { 2208fff24953c78bd58f3a42ac83b340b90e7e7228aCalin Juravle Runtime::Current()->RegisterSensitiveThread(); 2218fff24953c78bd58f3a42ac83b340b90e7e7228aCalin Juravle} 2228fff24953c78bd58f3a42ac83b340b90e7e7228aCalin Juravle 223987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartierstatic void VMRuntime_registerNativeFree(JNIEnv* env, jobject, jint bytes) { 2241eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers if (UNLIKELY(bytes < 0)) { 2251eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers ScopedObjectAccess soa(env); 226987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier ThrowRuntimeException("allocation size negative %d", bytes); 227987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier return; 228987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier } 2298ec31f9835a8d1513be9be7f9fa236fe4715750dMathieu Chartier Runtime::Current()->GetHeap()->RegisterNativeFree(env, static_cast<size_t>(bytes)); 230987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier} 231987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier 2326a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersstatic void VMRuntime_updateProcessState(JNIEnv*, jobject, jint process_state) { 2336a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers Runtime* runtime = Runtime::Current(); 234f8484c8b55f4b423048f94dfabbe44110a039a9bMathieu Chartier runtime->UpdateProcessState(static_cast<ProcessState>(process_state)); 235ca2a24da53869a04e1947aa46d06ccce5247d6f4Mathieu Chartier} 236ca2a24da53869a04e1947aa46d06ccce5247d6f4Mathieu Chartier 237a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartierstatic void VMRuntime_trimHeap(JNIEnv* env, jobject) { 238a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier Runtime::Current()->GetHeap()->Trim(ThreadForEnv(env)); 2398cf5bc0ab8742df107f0f4fc8ec0e991b6568f11Elliott Hughes} 2408cf5bc0ab8742df107f0f4fc8ec0e991b6568f11Elliott Hughes 24181d425b0b232962441616f8b14f73620bffef5e5Ian Rogersstatic void VMRuntime_concurrentGC(JNIEnv* env, jobject) { 2420ae98992d348b5bf3fc85a52d81b0e5f221f20d6Hiroshi Yamauchi Runtime::Current()->GetHeap()->ConcurrentGC(ThreadForEnv(env), true); 2437664f5cd118b355a5fe0c7536cb48ac991ed2b62Mathieu Chartier} 2447664f5cd118b355a5fe0c7536cb48ac991ed2b62Mathieu Chartier 245a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartierstatic void VMRuntime_requestHeapTrim(JNIEnv* env, jobject) { 246a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier Runtime::Current()->GetHeap()->RequestTrim(ThreadForEnv(env)); 247a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier} 248a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier 249079101a17575114622f6e1d5be5c9ba643630e9aMathieu Chartierstatic void VMRuntime_requestConcurrentGC(JNIEnv* env, jobject) { 2500ae98992d348b5bf3fc85a52d81b0e5f221f20d6Hiroshi Yamauchi Runtime::Current()->GetHeap()->RequestConcurrentGC(ThreadForEnv(env), true); 251079101a17575114622f6e1d5be5c9ba643630e9aMathieu Chartier} 252a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier 253a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartierstatic void VMRuntime_startHeapTaskProcessor(JNIEnv* env, jobject) { 254a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier Runtime::Current()->GetHeap()->GetTaskProcessor()->Start(ThreadForEnv(env)); 255a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier} 256a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier 257a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartierstatic void VMRuntime_stopHeapTaskProcessor(JNIEnv* env, jobject) { 258a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier Runtime::Current()->GetHeap()->GetTaskProcessor()->Stop(ThreadForEnv(env)); 259a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier} 260a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier 261a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartierstatic void VMRuntime_runHeapTasks(JNIEnv* env, jobject) { 262a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier Runtime::Current()->GetHeap()->GetTaskProcessor()->RunAllTasks(ThreadForEnv(env)); 263079101a17575114622f6e1d5be5c9ba643630e9aMathieu Chartier} 264079101a17575114622f6e1d5be5c9ba643630e9aMathieu Chartier 265e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstromtypedef std::map<std::string, mirror::String*> StringTable; 266e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 267bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass PreloadDexCachesStringsVisitor : public SingleRootVisitor { 268bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier public: 269d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier explicit PreloadDexCachesStringsVisitor(StringTable* table) : table_(table) { } 270bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 271bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoot(mirror::Object* root, const RootInfo& info ATTRIBUTE_UNUSED) 27290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_) { 273bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier mirror::String* string = root->AsString(); 274bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier table_->operator[](string->ToModifiedUtf8()) = string; 275bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier } 276bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 277bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier private: 278bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier StringTable* const table_; 279bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier}; 280e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 281e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom// Based on ClassLinker::ResolveString. 2822cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartierstatic void PreloadDexCachesResolveString( 2832cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier Handle<mirror::DexCache> dex_cache, uint32_t string_idx, StringTable& strings) 28490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 285e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom mirror::String* string = dex_cache->GetResolvedString(string_idx); 2862cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (string != nullptr) { 287e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 288e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 289e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const DexFile* dex_file = dex_cache->GetDexFile(); 290cf5077ac14f0922b6104a8a03fd66d97a490a3ddIan Rogers const char* utf8 = dex_file->StringDataByIdx(string_idx); 291e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom string = strings[utf8]; 2922cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (string == nullptr) { 293e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 294e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 295e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom // LOG(INFO) << "VMRuntime.preloadDexCaches resolved string=" << utf8; 296e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom dex_cache->SetResolvedString(string_idx, string); 297e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom} 298e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 299e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom// Based on ClassLinker::ResolveType. 3002cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartierstatic void PreloadDexCachesResolveType( 3012cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier Thread* self, mirror::DexCache* dex_cache, uint32_t type_idx) 30290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 303e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom mirror::Class* klass = dex_cache->GetResolvedType(type_idx); 3042cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (klass != nullptr) { 305e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 306e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 307e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const DexFile* dex_file = dex_cache->GetDexFile(); 308e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const char* class_name = dex_file->StringByTypeIdx(type_idx); 309e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom ClassLinker* linker = Runtime::Current()->GetClassLinker(); 310e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (class_name[1] == '\0') { 311e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom klass = linker->FindPrimitiveClass(class_name[0]); 312e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } else { 3132cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier klass = linker->LookupClass(self, class_name, ComputeModifiedUtf8Hash(class_name), nullptr); 314e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 3152cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (klass == nullptr) { 316e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 317e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 318e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom // LOG(INFO) << "VMRuntime.preloadDexCaches resolved klass=" << class_name; 319e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom dex_cache->SetResolvedType(type_idx, klass); 320e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom // Skip uninitialized classes because filled static storage entry implies it is initialized. 321e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (!klass->IsInitialized()) { 322e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom // LOG(INFO) << "VMRuntime.preloadDexCaches uninitialized klass=" << class_name; 323e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 324e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 325e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom // LOG(INFO) << "VMRuntime.preloadDexCaches static storage klass=" << class_name; 326e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom} 327e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 328e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom// Based on ClassLinker::ResolveField. 3290cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartierstatic void PreloadDexCachesResolveField(Handle<mirror::DexCache> dex_cache, uint32_t field_idx, 330e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom bool is_static) 33190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 332c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* field = dex_cache->GetResolvedField(field_idx, sizeof(void*)); 333c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier if (field != nullptr) { 334e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 335e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 336e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const DexFile* dex_file = dex_cache->GetDexFile(); 337e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const DexFile::FieldId& field_id = dex_file->GetFieldId(field_idx); 338f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier Thread* const self = Thread::Current(); 339f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier StackHandleScope<1> hs(self); 340f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier Handle<mirror::Class> klass(hs.NewHandle(dex_cache->GetResolvedType(field_id.class_idx_))); 3412cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (klass.Get() == nullptr) { 342e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 343e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 344e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (is_static) { 345f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier field = mirror::Class::FindStaticField(self, klass, dex_cache.Get(), field_idx); 346e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } else { 347eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier field = klass->FindInstanceField(dex_cache.Get(), field_idx); 348e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 3492cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (field == nullptr) { 350e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 351e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 352e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom // LOG(INFO) << "VMRuntime.preloadDexCaches resolved field " << PrettyField(field); 353c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier dex_cache->SetResolvedField(field_idx, field, sizeof(void*)); 354e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom} 355e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 356e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom// Based on ClassLinker::ResolveMethod. 3570cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartierstatic void PreloadDexCachesResolveMethod(Handle<mirror::DexCache> dex_cache, uint32_t method_idx, 358e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom InvokeType invoke_type) 35990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 360e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method = dex_cache->GetResolvedMethod(method_idx, sizeof(void*)); 3612cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (method != nullptr) { 362e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 363e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 364e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const DexFile* dex_file = dex_cache->GetDexFile(); 365e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const DexFile::MethodId& method_id = dex_file->GetMethodId(method_idx); 366e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom mirror::Class* klass = dex_cache->GetResolvedType(method_id.class_idx_); 3672cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (klass == nullptr) { 368e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 369e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 370e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom switch (invoke_type) { 371e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom case kDirect: 372e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom case kStatic: 373e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier method = klass->FindDirectMethod(dex_cache.Get(), method_idx, sizeof(void*)); 374e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom break; 375e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom case kInterface: 376e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier method = klass->FindInterfaceMethod(dex_cache.Get(), method_idx, sizeof(void*)); 377e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom break; 378e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom case kSuper: 379e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom case kVirtual: 380e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier method = klass->FindVirtualMethod(dex_cache.Get(), method_idx, sizeof(void*)); 381e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom break; 382e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom default: 383e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom LOG(FATAL) << "Unreachable - invocation type: " << invoke_type; 3842c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 385e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 3862cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (method == nullptr) { 387e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 388e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 389e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom // LOG(INFO) << "VMRuntime.preloadDexCaches resolved method " << PrettyMethod(method); 390e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier dex_cache->SetResolvedMethod(method_idx, method, sizeof(void*)); 391e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom} 392e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 393e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstromstruct DexCacheStats { 394e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom uint32_t num_strings; 395e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom uint32_t num_types; 396e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom uint32_t num_fields; 397e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom uint32_t num_methods; 398e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom DexCacheStats() : num_strings(0), 399e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom num_types(0), 400e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom num_fields(0), 4015ddb4104ac605d66693b55b79f26f8b8a5505e63Ian Rogers num_methods(0) {} 402e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom}; 403e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 404e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstromstatic const bool kPreloadDexCachesEnabled = true; 405e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 406e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom// Disabled because it takes a long time (extra half second) but 407e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom// gives almost no benefit in terms of saving private dirty pages. 408e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstromstatic const bool kPreloadDexCachesStrings = false; 409e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 410e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstromstatic const bool kPreloadDexCachesTypes = true; 411e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstromstatic const bool kPreloadDexCachesFieldsAndMethods = true; 412e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 413e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstromstatic const bool kPreloadDexCachesCollectStats = true; 414e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 415e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstromstatic void PreloadDexCachesStatsTotal(DexCacheStats* total) { 416e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (!kPreloadDexCachesCollectStats) { 417e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 418e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 419e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 420e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom ClassLinker* linker = Runtime::Current()->GetClassLinker(); 421e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const std::vector<const DexFile*>& boot_class_path = linker->GetBootClassPath(); 422e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom for (size_t i = 0; i< boot_class_path.size(); i++) { 423e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const DexFile* dex_file = boot_class_path[i]; 4242cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(dex_file != nullptr); 425e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom total->num_strings += dex_file->NumStringIds(); 426e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom total->num_fields += dex_file->NumFieldIds(); 427e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom total->num_methods += dex_file->NumMethodIds(); 428e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom total->num_types += dex_file->NumTypeIds(); 429e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 430e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom} 431e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 432e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstromstatic void PreloadDexCachesStatsFilled(DexCacheStats* filled) 43390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 434e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (!kPreloadDexCachesCollectStats) { 435673ed3d8aedc5462a47ded827c99f35d46525457Mathieu Chartier return; 436e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 437673ed3d8aedc5462a47ded827c99f35d46525457Mathieu Chartier ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); 438673ed3d8aedc5462a47ded827c99f35d46525457Mathieu Chartier Thread* const self = Thread::Current(); 439673ed3d8aedc5462a47ded827c99f35d46525457Mathieu Chartier for (const DexFile* dex_file : class_linker->GetBootClassPath()) { 4402cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(dex_file != nullptr); 441673ed3d8aedc5462a47ded827c99f35d46525457Mathieu Chartier mirror::DexCache* const dex_cache = class_linker->FindDexCache(self, *dex_file, true); 442673ed3d8aedc5462a47ded827c99f35d46525457Mathieu Chartier // If dex cache was deallocated, just continue. 443673ed3d8aedc5462a47ded827c99f35d46525457Mathieu Chartier if (dex_cache == nullptr) { 444673ed3d8aedc5462a47ded827c99f35d46525457Mathieu Chartier continue; 445673ed3d8aedc5462a47ded827c99f35d46525457Mathieu Chartier } 446277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe for (size_t j = 0; j < dex_cache->NumStrings(); j++) { 447277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe mirror::String* string = dex_cache->GetResolvedString(j); 4482cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (string != nullptr) { 449e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom filled->num_strings++; 450e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 451e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 452277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe for (size_t j = 0; j < dex_cache->NumResolvedTypes(); j++) { 453277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe mirror::Class* klass = dex_cache->GetResolvedType(j); 4542cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (klass != nullptr) { 455e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom filled->num_types++; 456e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 457e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 458277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe for (size_t j = 0; j < dex_cache->NumResolvedFields(); j++) { 459673ed3d8aedc5462a47ded827c99f35d46525457Mathieu Chartier ArtField* field = class_linker->GetResolvedField(j, dex_cache); 4602cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (field != nullptr) { 461e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom filled->num_fields++; 462e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 463e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 464277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe for (size_t j = 0; j < dex_cache->NumResolvedMethods(); j++) { 465e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method = dex_cache->GetResolvedMethod(j, sizeof(void*)); 4662cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (method != nullptr) { 467e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom filled->num_methods++; 468e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 469e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 470e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 471e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom} 472e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 473e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom// TODO: http://b/11309598 This code was ported over based on the 474e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom// Dalvik version. However, ART has similar code in other places such 475e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom// as the CompilerDriver. This code could probably be refactored to 476e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom// serve both uses. 477e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstromstatic void VMRuntime_preloadDexCaches(JNIEnv* env, jobject) { 478e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (!kPreloadDexCachesEnabled) { 479e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom return; 480e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 481e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 482e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom ScopedObjectAccess soa(env); 483e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 484e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom DexCacheStats total; 485e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom DexCacheStats before; 486e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (kPreloadDexCachesCollectStats) { 487e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom LOG(INFO) << "VMRuntime.preloadDexCaches starting"; 488e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom PreloadDexCachesStatsTotal(&total); 489e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom PreloadDexCachesStatsFilled(&before); 490e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 491e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 492e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom Runtime* runtime = Runtime::Current(); 493e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom ClassLinker* linker = runtime->GetClassLinker(); 494e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 495e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom // We use a std::map to avoid heap allocating StringObjects to lookup in gDvm.literalStrings 496e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom StringTable strings; 497e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (kPreloadDexCachesStrings) { 498bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier PreloadDexCachesStringsVisitor visitor(&strings); 499bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier runtime->GetInternTable()->VisitRoots(&visitor, kVisitRootFlagAllRoots); 500e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 501e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 502e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const std::vector<const DexFile*>& boot_class_path = linker->GetBootClassPath(); 503673ed3d8aedc5462a47ded827c99f35d46525457Mathieu Chartier for (size_t i = 0; i < boot_class_path.size(); i++) { 504e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const DexFile* dex_file = boot_class_path[i]; 5052cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(dex_file != nullptr); 5067b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers StackHandleScope<1> hs(soa.Self()); 507c9dbb1df3b5c06ba122cacaf35b17cb53c6be3c6Mathieu Chartier Handle<mirror::DexCache> dex_cache(hs.NewHandle(linker->RegisterDexFile(*dex_file, nullptr))); 508e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 509e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (kPreloadDexCachesStrings) { 510277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe for (size_t j = 0; j < dex_cache->NumStrings(); j++) { 511277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe PreloadDexCachesResolveString(dex_cache, j, strings); 512e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 513e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 514e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 515e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (kPreloadDexCachesTypes) { 516277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe for (size_t j = 0; j < dex_cache->NumResolvedTypes(); j++) { 517277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe PreloadDexCachesResolveType(soa.Self(), dex_cache.Get(), j); 518e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 519e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 520e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 521e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (kPreloadDexCachesFieldsAndMethods) { 522e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom for (size_t class_def_index = 0; 523e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom class_def_index < dex_file->NumClassDefs(); 524e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom class_def_index++) { 525e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index); 52613735955f39b3b304c37d2b2840663c131262c18Ian Rogers const uint8_t* class_data = dex_file->GetClassData(class_def); 5272cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (class_data == nullptr) { 528e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom continue; 529e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 530e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom ClassDataItemIterator it(*dex_file, class_data); 531e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom for (; it.HasNextStaticField(); it.Next()) { 532e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom uint32_t field_idx = it.GetMemberIndex(); 533e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom PreloadDexCachesResolveField(dex_cache, field_idx, true); 534e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 535e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom for (; it.HasNextInstanceField(); it.Next()) { 536e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom uint32_t field_idx = it.GetMemberIndex(); 537e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom PreloadDexCachesResolveField(dex_cache, field_idx, false); 538e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 539e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom for (; it.HasNextDirectMethod(); it.Next()) { 540e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom uint32_t method_idx = it.GetMemberIndex(); 541e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom InvokeType invoke_type = it.GetMethodInvokeType(class_def); 542e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom PreloadDexCachesResolveMethod(dex_cache, method_idx, invoke_type); 543e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 544e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom for (; it.HasNextVirtualMethod(); it.Next()) { 545e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom uint32_t method_idx = it.GetMemberIndex(); 546e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom InvokeType invoke_type = it.GetMethodInvokeType(class_def); 547e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom PreloadDexCachesResolveMethod(dex_cache, method_idx, invoke_type); 548e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 549e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 550e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 551e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 552e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 553e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom if (kPreloadDexCachesCollectStats) { 554e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom DexCacheStats after; 555e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom PreloadDexCachesStatsFilled(&after); 556e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches strings total=%d before=%d after=%d", 557e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom total.num_strings, before.num_strings, after.num_strings); 558e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches types total=%d before=%d after=%d", 559e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom total.num_types, before.num_types, after.num_types); 560e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches fields total=%d before=%d after=%d", 561e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom total.num_fields, before.num_fields, after.num_fields); 562e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches methods total=%d before=%d after=%d", 563e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom total.num_methods, before.num_methods, after.num_methods); 564e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom LOG(INFO) << StringPrintf("VMRuntime.preloadDexCaches finished"); 565e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom } 566e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom} 567e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom 5680aded089f565008ba5908e395e5914ca4f91f2deDave Allison 5690aded089f565008ba5908e395e5914ca4f91f2deDave Allison/* 5700aded089f565008ba5908e395e5914ca4f91f2deDave Allison * This is called by the framework when it knows the application directory and 57131f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle * process name. 5720aded089f565008ba5908e395e5914ca4f91f2deDave Allison */ 57331f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravlestatic void VMRuntime_registerAppInfo(JNIEnv* env, 57431f2c155975c5794d481df03eb0947cb48d2c6b5Calin Juravle jclass clazz ATTRIBUTE_UNUSED, 5755e2b971e468ca73a8e10a120730b3b6f17fad408Calin Juravle jstring profile_file, 57686a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle jstring app_dir, 57786a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle jobjectArray code_paths, 57886a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle jstring foreign_dex_profile_path) { 57966f55237679db90cb0a0a265043a787932b466f8Calin Juravle std::vector<std::string> code_paths_vec; 58066f55237679db90cb0a0a265043a787932b466f8Calin Juravle int code_paths_length = env->GetArrayLength(code_paths); 58166f55237679db90cb0a0a265043a787932b466f8Calin Juravle for (int i = 0; i < code_paths_length; i++) { 58266f55237679db90cb0a0a265043a787932b466f8Calin Juravle jstring code_path = reinterpret_cast<jstring>(env->GetObjectArrayElement(code_paths, i)); 58366f55237679db90cb0a0a265043a787932b466f8Calin Juravle const char* raw_code_path = env->GetStringUTFChars(code_path, nullptr); 58466f55237679db90cb0a0a265043a787932b466f8Calin Juravle code_paths_vec.push_back(raw_code_path); 58566f55237679db90cb0a0a265043a787932b466f8Calin Juravle env->ReleaseStringUTFChars(code_path, raw_code_path); 58666f55237679db90cb0a0a265043a787932b466f8Calin Juravle } 587c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle 5885e2b971e468ca73a8e10a120730b3b6f17fad408Calin Juravle const char* raw_profile_file = env->GetStringUTFChars(profile_file, nullptr); 5895e2b971e468ca73a8e10a120730b3b6f17fad408Calin Juravle std::string profile_file_str(raw_profile_file); 5905e2b971e468ca73a8e10a120730b3b6f17fad408Calin Juravle env->ReleaseStringUTFChars(profile_file, raw_profile_file); 591c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle 59286a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle std::string foreign_dex_profile_path_str = ""; 59386a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle if (foreign_dex_profile_path != nullptr) { 59486a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle const char* raw_foreign_dex_profile_path = 59586a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle env->GetStringUTFChars(foreign_dex_profile_path, nullptr); 59686a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle foreign_dex_profile_path_str.assign(raw_foreign_dex_profile_path); 59786a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle env->ReleaseStringUTFChars(foreign_dex_profile_path, raw_foreign_dex_profile_path); 59886a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle } 59986a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle 60086a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle const char* raw_app_dir = env->GetStringUTFChars(app_dir, nullptr); 60186a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle std::string app_dir_str(raw_app_dir); 60286a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle env->ReleaseStringUTFChars(app_dir, raw_app_dir); 60386a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle 60486a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle Runtime::Current()->RegisterAppInfo(code_paths_vec, 60586a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle profile_file_str, 60686a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle foreign_dex_profile_path_str, 60786a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle app_dir_str); 6080aded089f565008ba5908e395e5914ca4f91f2deDave Allison} 6090aded089f565008ba5908e395e5914ca4f91f2deDave Allison 61031d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstromstatic jboolean VMRuntime_isBootClassPathOnDisk(JNIEnv* env, jclass, jstring java_instruction_set) { 61131d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom ScopedUtfChars instruction_set(env, java_instruction_set); 61231d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom if (instruction_set.c_str() == nullptr) { 61331d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom return JNI_FALSE; 61431d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom } 61531d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom InstructionSet isa = GetInstructionSetFromString(instruction_set.c_str()); 61631d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom if (isa == kNone) { 61731d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom ScopedLocalRef<jclass> iae(env, env->FindClass("java/lang/IllegalArgumentException")); 61831d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom std::string message(StringPrintf("Instruction set %s is invalid.", instruction_set.c_str())); 61931d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom env->ThrowNew(iae.get(), message.c_str()); 62031d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom return JNI_FALSE; 62131d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom } 62231d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom std::string error_msg; 62331d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom std::unique_ptr<ImageHeader> image_header(gc::space::ImageSpace::ReadImageHeader( 62431d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom Runtime::Current()->GetImageLocation().c_str(), isa, &error_msg)); 62531d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom return image_header.get() != nullptr; 62631d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom} 62731d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom 62831d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstromstatic jstring VMRuntime_getCurrentInstructionSet(JNIEnv* env, jclass) { 62931d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom return env->NewStringUTF(GetInstructionSetString(kRuntimeISA)); 63031d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom} 63131d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom 6327ef1b4b20bd7cf485f5e443927c1e6fa797a0439Andreas Gampestatic jboolean VMRuntime_didPruneDalvikCache(JNIEnv* env ATTRIBUTE_UNUSED, 6337ef1b4b20bd7cf485f5e443927c1e6fa797a0439Andreas Gampe jclass klass ATTRIBUTE_UNUSED) { 6347ef1b4b20bd7cf485f5e443927c1e6fa797a0439Andreas Gampe return Runtime::Current()->GetPrunedDalvikCache() ? JNI_TRUE : JNI_FALSE; 6357ef1b4b20bd7cf485f5e443927c1e6fa797a0439Andreas Gampe} 6367ef1b4b20bd7cf485f5e443927c1e6fa797a0439Andreas Gampe 6370512f02dd6623c0870c11fbf3274d7462f732136Elliott Hughesstatic JNINativeMethod gMethods[] = { 6381eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(VMRuntime, addressOf, "!(Ljava/lang/Object;)J"), 6397ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes NATIVE_METHOD(VMRuntime, bootClassPath, "()Ljava/lang/String;"), 640379d09fe3c3feb7c2a2fb5a3623689b5ace7e79bMathieu Chartier NATIVE_METHOD(VMRuntime, clampGrowthLimit, "()V"), 6417ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes NATIVE_METHOD(VMRuntime, classPath, "()Ljava/lang/String;"), 6427ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes NATIVE_METHOD(VMRuntime, clearGrowthLimit, "()V"), 6437664f5cd118b355a5fe0c7536cb48ac991ed2b62Mathieu Chartier NATIVE_METHOD(VMRuntime, concurrentGC, "()V"), 6447ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes NATIVE_METHOD(VMRuntime, disableJitCompilation, "()V"), 6457ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes NATIVE_METHOD(VMRuntime, getTargetHeapUtilization, "()F"), 64653b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers NATIVE_METHOD(VMRuntime, isDebuggerActive, "!()Z"), 647dfbbeef151d52ec9c5bbc9f12449d4c74b8ec19eOleksiy Vyalov NATIVE_METHOD(VMRuntime, isNativeDebuggable, "!()Z"), 6487ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes NATIVE_METHOD(VMRuntime, nativeSetTargetHeapUtilization, "(F)V"), 6491eb512d33f94d1dd7ea38263307ba0f7a0dfa653Ian Rogers NATIVE_METHOD(VMRuntime, newNonMovableArray, "!(Ljava/lang/Class;I)Ljava/lang/Object;"), 650f9c612f2e657adb0764285256b228622e0789254Ian Rogers NATIVE_METHOD(VMRuntime, newUnpaddedArray, "!(Ljava/lang/Class;I)Ljava/lang/Object;"), 6517ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes NATIVE_METHOD(VMRuntime, properties, "()[Ljava/lang/String;"), 652881392f55e566a7c6407e7d321a31836d2d8865fAlex Klyubin NATIVE_METHOD(VMRuntime, setTargetSdkVersionNative, "(I)V"), 653987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier NATIVE_METHOD(VMRuntime, registerNativeAllocation, "(I)V"), 6548fff24953c78bd58f3a42ac83b340b90e7e7228aCalin Juravle NATIVE_METHOD(VMRuntime, registerSensitiveThread, "()V"), 655987ccff48fe2c0645756e1089608e4b6b7e9f7bfMathieu Chartier NATIVE_METHOD(VMRuntime, registerNativeFree, "(I)V"), 656a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier NATIVE_METHOD(VMRuntime, requestConcurrentGC, "()V"), 657a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier NATIVE_METHOD(VMRuntime, requestHeapTrim, "()V"), 658a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier NATIVE_METHOD(VMRuntime, runHeapTasks, "()V"), 659ca2a24da53869a04e1947aa46d06ccce5247d6f4Mathieu Chartier NATIVE_METHOD(VMRuntime, updateProcessState, "(I)V"), 660a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier NATIVE_METHOD(VMRuntime, startHeapTaskProcessor, "()V"), 6617ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes NATIVE_METHOD(VMRuntime, startJitCompilation, "()V"), 662a5eae69589ff562ad66c57665882cd16f237321cMathieu Chartier NATIVE_METHOD(VMRuntime, stopHeapTaskProcessor, "()V"), 6638cf5bc0ab8742df107f0f4fc8ec0e991b6568f11Elliott Hughes NATIVE_METHOD(VMRuntime, trimHeap, "()V"), 6647ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes NATIVE_METHOD(VMRuntime, vmVersion, "()Ljava/lang/String;"), 665cef450c613d8324db7c418130596182b8e9a5cddBrian Carlstrom NATIVE_METHOD(VMRuntime, vmLibrary, "()Ljava/lang/String;"), 666a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz NATIVE_METHOD(VMRuntime, vmInstructionSet, "()Ljava/lang/String;"), 667a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz NATIVE_METHOD(VMRuntime, is64Bit, "!()Z"), 668a705376e3355fd307bfbf7bf72d6944c63a9f2f7Sebastien Hertz NATIVE_METHOD(VMRuntime, isCheckJniEnabled, "!()Z"), 669e810452722ac83b294d1f7aa80bdd88e547d5af0Brian Carlstrom NATIVE_METHOD(VMRuntime, preloadDexCaches, "()V"), 67031d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom NATIVE_METHOD(VMRuntime, registerAppInfo, 67186a9ebe4197e963249ffbbaa1830da97ed642fa5Calin Juravle "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V"), 67231d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom NATIVE_METHOD(VMRuntime, isBootClassPathOnDisk, "(Ljava/lang/String;)Z"), 67331d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom NATIVE_METHOD(VMRuntime, getCurrentInstructionSet, "()Ljava/lang/String;"), 6747ef1b4b20bd7cf485f5e443927c1e6fa797a0439Andreas Gampe NATIVE_METHOD(VMRuntime, didPruneDalvikCache, "()Z"), 6757ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes}; 6767ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 6777ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughesvoid register_dalvik_system_VMRuntime(JNIEnv* env) { 678eac766769e3114a078c188ea26776a81f0edb3cfElliott Hughes REGISTER_NATIVE_METHODS("dalvik/system/VMRuntime"); 6797ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} 6807ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes 6817ede61eceed2f8da14a4fff05c57c748c160d57fElliott Hughes} // namespace art 682