1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * dalvik.system.VMRuntime 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 2189383030aca8f77aeab73540404ba332ce5ac035Elliott Hughes#include "ScopedPthreadMutexLock.h" 22fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom#include "UniquePtr.h" 23fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom#include "alloc/HeapSource.h" 24fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom#include "alloc/Visit.h" 25fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom#include "libdex/DexClass.h" 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "native/InternalNativePriv.h" 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <limits.h> 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom#include <map> 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * public native float getTargetHeapUtilization() 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the current ideal heap utilization, represented as a number 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * between zero and one. 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMRuntime_getTargetHeapUtilization( 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u4* args, JValue* pResult) 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UNUSED_PARAMETER(args); 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_FLOAT(dvmGetTargetHeapUtilization()); 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * native float nativeSetTargetHeapUtilization() 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets the current ideal heap utilization, represented as a number 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * between zero and one. Returns the old utilization. 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that this is NOT static. 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Dalvik_dalvik_system_VMRuntime_nativeSetTargetHeapUtilization( 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const u4* args, JValue* pResult) 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmSetTargetHeapUtilization(dvmU4ToFloat(args[1])); 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RETURN_VOID(); 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 63a97ed1382c4e74704b44d366cf464bef5757c6b0Ben Cheng * public native void startJitCompilation() 646bad6a2d77bcfeebf1f5a24406f49bda88503353Ben Cheng * 656bad6a2d77bcfeebf1f5a24406f49bda88503353Ben Cheng * Callback function from the framework to indicate that an app has gone 666bad6a2d77bcfeebf1f5a24406f49bda88503353Ben Cheng * through the startup phase and it is time to enable the JIT compiler. 676bad6a2d77bcfeebf1f5a24406f49bda88503353Ben Cheng */ 68a97ed1382c4e74704b44d366cf464bef5757c6b0Ben Chengstatic void Dalvik_dalvik_system_VMRuntime_startJitCompilation(const u4* args, 696bad6a2d77bcfeebf1f5a24406f49bda88503353Ben Cheng JValue* pResult) 706bad6a2d77bcfeebf1f5a24406f49bda88503353Ben Cheng{ 716bad6a2d77bcfeebf1f5a24406f49bda88503353Ben Cheng#if defined(WITH_JIT) 7289383030aca8f77aeab73540404ba332ce5ac035Elliott Hughes if (gDvm.executionMode == kExecutionModeJit && gDvmJit.disableJit == false) { 7389383030aca8f77aeab73540404ba332ce5ac035Elliott Hughes ScopedPthreadMutexLock lock(&gDvmJit.compilerLock); 74f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng gDvmJit.alreadyEnabledViaFramework = true; 7596cfe6c39b91dabc78182e2f7676b27b4012886aBill Buzbee pthread_cond_signal(&gDvmJit.compilerQueueActivity); 7696cfe6c39b91dabc78182e2f7676b27b4012886aBill Buzbee } 7794d89f8016b6c305ab0df491874dcedb252ecfccBill Buzbee#endif 786bad6a2d77bcfeebf1f5a24406f49bda88503353Ben Cheng RETURN_VOID(); 796bad6a2d77bcfeebf1f5a24406f49bda88503353Ben Cheng} 806bad6a2d77bcfeebf1f5a24406f49bda88503353Ben Cheng 81f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng/* 82f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng * public native void disableJitCompilation() 83f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng * 84f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng * Callback function from the framework to indicate that a VM instance wants to 85f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng * permanently disable the JIT compiler. Currently only the system server uses 86f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng * this interface when it detects system-wide safe mode is enabled. 87f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng */ 88f30acbb249b137b049500f136d2bb273c0b6221aBen Chengstatic void Dalvik_dalvik_system_VMRuntime_disableJitCompilation(const u4* args, 89f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng JValue* pResult) 90f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng{ 91f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng#if defined(WITH_JIT) 92f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng if (gDvm.executionMode == kExecutionModeJit) { 93f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng gDvmJit.disableJit = true; 94f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng } 95f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng#endif 96f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng RETURN_VOID(); 97f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng} 98f30acbb249b137b049500f136d2bb273c0b6221aBen Cheng 99f5949168d4142cde1582117173b03c614b632938Elliott Hughesstatic void Dalvik_dalvik_system_VMRuntime_newNonMovableArray(const u4* args, 100f5949168d4142cde1582117173b03c614b632938Elliott Hughes JValue* pResult) 101f5949168d4142cde1582117173b03c614b632938Elliott Hughes{ 102f5949168d4142cde1582117173b03c614b632938Elliott Hughes ClassObject* elementClass = (ClassObject*) args[1]; 103f5949168d4142cde1582117173b03c614b632938Elliott Hughes int length = args[2]; 104f5949168d4142cde1582117173b03c614b632938Elliott Hughes 105f5949168d4142cde1582117173b03c614b632938Elliott Hughes if (elementClass == NULL) { 106a8b4a0eec5e3ab181b3d26223c84c556bead06c8Elliott Hughes dvmThrowNullPointerException("elementClass == null"); 107f5949168d4142cde1582117173b03c614b632938Elliott Hughes RETURN_VOID(); 108f5949168d4142cde1582117173b03c614b632938Elliott Hughes } 109f5949168d4142cde1582117173b03c614b632938Elliott Hughes if (length < 0) { 1102c8e25b2010d1bba4dca0148691bc6e1a4ee7616Dan Bornstein dvmThrowNegativeArraySizeException(length); 111f5949168d4142cde1582117173b03c614b632938Elliott Hughes RETURN_VOID(); 112f5949168d4142cde1582117173b03c614b632938Elliott Hughes } 113f5949168d4142cde1582117173b03c614b632938Elliott Hughes 114f5949168d4142cde1582117173b03c614b632938Elliott Hughes // TODO: right now, we don't have a copying collector, so there's no need 115f5949168d4142cde1582117173b03c614b632938Elliott Hughes // to do anything special here, but we ought to pass the non-movability 116f5949168d4142cde1582117173b03c614b632938Elliott Hughes // through to the allocator. 117c233f165a425ce44c7e5e75b14bc4fc018288345Carl Shapiro ClassObject* arrayClass = dvmFindArrayClassForElement(elementClass); 118c233f165a425ce44c7e5e75b14bc4fc018288345Carl Shapiro ArrayObject* newArray = dvmAllocArrayByClass(arrayClass, 119c233f165a425ce44c7e5e75b14bc4fc018288345Carl Shapiro length, 12052e2626eb3bf620c53459a90d912733de2ce0369Carl Shapiro ALLOC_NON_MOVING); 121f5949168d4142cde1582117173b03c614b632938Elliott Hughes if (newArray == NULL) { 122f5949168d4142cde1582117173b03c614b632938Elliott Hughes assert(dvmCheckException(dvmThreadSelf())); 123f5949168d4142cde1582117173b03c614b632938Elliott Hughes RETURN_VOID(); 124f5949168d4142cde1582117173b03c614b632938Elliott Hughes } 125f5949168d4142cde1582117173b03c614b632938Elliott Hughes dvmReleaseTrackedAlloc((Object*) newArray, NULL); 126f5949168d4142cde1582117173b03c614b632938Elliott Hughes 127f5949168d4142cde1582117173b03c614b632938Elliott Hughes RETURN_PTR(newArray); 128f5949168d4142cde1582117173b03c614b632938Elliott Hughes} 129f5949168d4142cde1582117173b03c614b632938Elliott Hughes 130f5949168d4142cde1582117173b03c614b632938Elliott Hughesstatic void Dalvik_dalvik_system_VMRuntime_addressOf(const u4* args, 131f5949168d4142cde1582117173b03c614b632938Elliott Hughes JValue* pResult) 132f5949168d4142cde1582117173b03c614b632938Elliott Hughes{ 133f5949168d4142cde1582117173b03c614b632938Elliott Hughes ArrayObject* array = (ArrayObject*) args[1]; 13419f4f02d096e549c1aaabdb5e8fa317588ab0bfdElliott Hughes if (!dvmIsArray(array)) { 135d27f3cf3e7b373487f39e035fc4b55168d55c454Dan Bornstein dvmThrowIllegalArgumentException(NULL); 13619f4f02d096e549c1aaabdb5e8fa317588ab0bfdElliott Hughes RETURN_VOID(); 13719f4f02d096e549c1aaabdb5e8fa317588ab0bfdElliott Hughes } 13819f4f02d096e549c1aaabdb5e8fa317588ab0bfdElliott Hughes // TODO: we should also check that this is a non-movable array. 139f5949168d4142cde1582117173b03c614b632938Elliott Hughes s8 result = (uintptr_t) array->contents; 140f5949168d4142cde1582117173b03c614b632938Elliott Hughes RETURN_LONG(result); 141f5949168d4142cde1582117173b03c614b632938Elliott Hughes} 142f5949168d4142cde1582117173b03c614b632938Elliott Hughes 143df9f08b877ecfd8ebadea822bb9e066ee7d30433Carl Shapirostatic void Dalvik_dalvik_system_VMRuntime_clearGrowthLimit(const u4* args, 144df9f08b877ecfd8ebadea822bb9e066ee7d30433Carl Shapiro JValue* pResult) 145df9f08b877ecfd8ebadea822bb9e066ee7d30433Carl Shapiro{ 146df9f08b877ecfd8ebadea822bb9e066ee7d30433Carl Shapiro dvmClearGrowthLimit(); 147df9f08b877ecfd8ebadea822bb9e066ee7d30433Carl Shapiro RETURN_VOID(); 148df9f08b877ecfd8ebadea822bb9e066ee7d30433Carl Shapiro} 149df9f08b877ecfd8ebadea822bb9e066ee7d30433Carl Shapiro 150e58a9b5d443cd3fcc22abc887cf0739a4b6bc145Jesse Wilsonstatic void Dalvik_dalvik_system_VMRuntime_isDebuggerActive( 151e58a9b5d443cd3fcc22abc887cf0739a4b6bc145Jesse Wilson const u4* args, JValue* pResult) 152e58a9b5d443cd3fcc22abc887cf0739a4b6bc145Jesse Wilson{ 153e58a9b5d443cd3fcc22abc887cf0739a4b6bc145Jesse Wilson RETURN_BOOLEAN(gDvm.debuggerActive || gDvm.nativeDebuggerActive); 154e58a9b5d443cd3fcc22abc887cf0739a4b6bc145Jesse Wilson} 155e58a9b5d443cd3fcc22abc887cf0739a4b6bc145Jesse Wilson 15649dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughesstatic void Dalvik_dalvik_system_VMRuntime_properties(const u4* args, 15749dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes JValue* pResult) 15849dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes{ 159689cc333b7be28b8b312f91999a31a2b0bd60c62Elliott Hughes ArrayObject* result = dvmCreateStringArray(*gDvm.properties); 16049dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes dvmReleaseTrackedAlloc((Object*) result, dvmThreadSelf()); 16149dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes RETURN_PTR(result); 16249dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes} 16349dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes 16449dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughesstatic void returnCString(JValue* pResult, const char* s) 16549dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes{ 16649dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes Object* result = (Object*) dvmCreateStringFromCstr(s); 16749dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes dvmReleaseTrackedAlloc(result, dvmThreadSelf()); 16849dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes RETURN_PTR(result); 16949dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes} 17049dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes 17149dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughesstatic void Dalvik_dalvik_system_VMRuntime_bootClassPath(const u4* args, 17249dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes JValue* pResult) 17349dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes{ 17449dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes returnCString(pResult, gDvm.bootClassPathStr); 17549dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes} 17649dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes 17749dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughesstatic void Dalvik_dalvik_system_VMRuntime_classPath(const u4* args, 17849dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes JValue* pResult) 17949dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes{ 18049dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes returnCString(pResult, gDvm.classPathStr); 18149dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes} 18249dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes 18349dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughesstatic void Dalvik_dalvik_system_VMRuntime_vmVersion(const u4* args, 18449dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes JValue* pResult) 18549dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes{ 18649dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes char buf[64]; 18749dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes sprintf(buf, "%d.%d.%d", 18849dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes DALVIK_MAJOR_VERSION, DALVIK_MINOR_VERSION, DALVIK_BUG_VERSION); 18949dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes returnCString(pResult, buf); 19049dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes} 19149dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes 192b86671d65bf4260feb2c51131dd942402b56d943Brian Carlstromstatic void Dalvik_dalvik_system_VMRuntime_vmLibrary(const u4* args, 193b86671d65bf4260feb2c51131dd942402b56d943Brian Carlstrom JValue* pResult) 194b86671d65bf4260feb2c51131dd942402b56d943Brian Carlstrom{ 195b86671d65bf4260feb2c51131dd942402b56d943Brian Carlstrom returnCString(pResult, "libdvm.so"); 196b86671d65bf4260feb2c51131dd942402b56d943Brian Carlstrom} 197b86671d65bf4260feb2c51131dd942402b56d943Brian Carlstrom 198191a799160fe811d8558724bb86cfe543b7efc2fElliott Hughesstatic void Dalvik_dalvik_system_VMRuntime_setTargetSdkVersion(const u4* args, 199191a799160fe811d8558724bb86cfe543b7efc2fElliott Hughes JValue* pResult) 200191a799160fe811d8558724bb86cfe543b7efc2fElliott Hughes{ 201191a799160fe811d8558724bb86cfe543b7efc2fElliott Hughes // This is the target SDK version of the app we're about to run. 202191a799160fe811d8558724bb86cfe543b7efc2fElliott Hughes // Note that this value may be CUR_DEVELOPMENT (10000). 203ea333384b92db9c400be1b4c8cb6992d9ba5f14dElliott Hughes // Note that this value may be 0, meaning "current". 204ed94ff793680873d2c942641ccda9ea81c95b5adElliott Hughes int targetSdkVersion = args[1]; 205ed94ff793680873d2c942641ccda9ea81c95b5adElliott Hughes if (targetSdkVersion > 0 && targetSdkVersion <= 13 /* honeycomb-mr2 */) { 206657124e8db7b2c6a77d7dbe6284645a04b8d9d65Ian Rogers if (gDvmJni.useCheckJni) { 207657124e8db7b2c6a77d7dbe6284645a04b8d9d65Ian Rogers ALOGI("CheckJNI enabled: not enabling JNI app bug workarounds."); 208657124e8db7b2c6a77d7dbe6284645a04b8d9d65Ian Rogers } else { 209657124e8db7b2c6a77d7dbe6284645a04b8d9d65Ian Rogers ALOGI("Enabling JNI app bug workarounds for target SDK version %i...", 210657124e8db7b2c6a77d7dbe6284645a04b8d9d65Ian Rogers targetSdkVersion); 211657124e8db7b2c6a77d7dbe6284645a04b8d9d65Ian Rogers gDvmJni.workAroundAppJniBugs = true; 212657124e8db7b2c6a77d7dbe6284645a04b8d9d65Ian Rogers } 213191a799160fe811d8558724bb86cfe543b7efc2fElliott Hughes } 214191a799160fe811d8558724bb86cfe543b7efc2fElliott Hughes RETURN_VOID(); 215191a799160fe811d8558724bb86cfe543b7efc2fElliott Hughes} 216191a799160fe811d8558724bb86cfe543b7efc2fElliott Hughes 2173086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartierstatic void Dalvik_dalvik_system_VMRuntime_registerNativeAllocation(const u4* args, 2183086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier JValue* pResult) 2193086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier{ 2203086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier int bytes = args[1]; 2213086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier if (bytes < 0) { 2223086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier dvmThrowRuntimeException("allocation size negative"); 2233086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier } else { 2243086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier dvmHeapSourceRegisterNativeAllocation(bytes); 2253086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier } 2263086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier RETURN_VOID(); 2273086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier} 2283086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier 2293086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartierstatic void Dalvik_dalvik_system_VMRuntime_registerNativeFree(const u4* args, 2303086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier JValue* pResult) 2313086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier{ 2323086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier int bytes = args[1]; 2333086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier if (bytes < 0) { 2343086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier dvmThrowRuntimeException("allocation size negative"); 2353086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier } else { 2363086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier dvmHeapSourceRegisterNativeFree(bytes); 2373086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier } 2383086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier RETURN_VOID(); 2393086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier} 2403086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier 241fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic DvmDex* getDvmDexFromClassPathEntry(ClassPathEntry* cpe) { 242fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (cpe->kind == kCpeDex) { 243fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return ((RawDexFile*) cpe->ptr)->pDvmDex; 244fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 245fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (cpe->kind == kCpeJar) { 246fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return ((JarFile*) cpe->ptr)->pDvmDex; 247fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 248fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom LOG_ALWAYS_FATAL("Unknown cpe->kind=%d", cpe->kind); 249fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom} 250fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 251fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromtypedef std::map<std::string, StringObject*> StringTable; 252fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 253fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic void preloadDexCachesStringsVisitor(void* addr, u4 threadId, RootType type, void* arg) { 254fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom StringTable& table = *(StringTable*) arg; 255fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom StringObject* strObj = *(StringObject**) addr; 256fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom LOG_FATAL_IF(strObj->clazz != gDvm.classJavaLangString, "Unknown class for supposed string"); 257fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom char* newStr = dvmCreateCstrFromString(strObj); 258fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // ALOGI("VMRuntime.preloadDexCaches interned=%s", newStr); 259fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom table[newStr] = strObj; 260fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom free(newStr); 261fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom} 262fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 263fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom// Based on dvmResolveString. 264fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic void preloadDexCachesResolveString(DvmDex* pDvmDex, 265fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom uint32_t stringIdx, 266fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom StringTable& strings) { 267fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom StringObject* string = dvmDexGetResolvedString(pDvmDex, stringIdx); 268fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (string != NULL) { 269fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 270fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 271fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexFile* pDexFile = pDvmDex->pDexFile; 272fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom uint32_t utf16Size; 273fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const char* utf8 = dexStringAndSizeById(pDexFile, stringIdx, &utf16Size); 274fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom string = strings[utf8]; 275fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (string == NULL) { 276fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 277fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 278fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // ALOGI("VMRuntime.preloadDexCaches found string=%s", utf8); 279fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom dvmDexSetResolvedString(pDvmDex, stringIdx, string); 280fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom} 281fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 282fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom// Based on dvmResolveClass. 283fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic void preloadDexCachesResolveType(DvmDex* pDvmDex, uint32_t typeIdx) { 284fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom ClassObject* clazz = dvmDexGetResolvedClass(pDvmDex, typeIdx); 285fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (clazz != NULL) { 286fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 287fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 288fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexFile* pDexFile = pDvmDex->pDexFile; 289fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const char* className = dexStringByTypeIdx(pDexFile, typeIdx); 290fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (className[0] != '\0' && className[1] == '\0') { 291fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom /* primitive type */ 292fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom clazz = dvmFindPrimitiveClass(className[0]); 293fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } else { 294fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom clazz = dvmLookupClass(className, NULL, true); 295fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 296fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (clazz == NULL) { 297fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 298fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 299fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // Skip uninitialized classes because filled cache entry implies it is initialized. 300fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (!dvmIsClassInitialized(clazz)) { 301fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // ALOGI("VMRuntime.preloadDexCaches uninitialized clazz=%s", className); 302fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 303fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 304fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // ALOGI("VMRuntime.preloadDexCaches found clazz=%s", className); 305fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom dvmDexSetResolvedClass(pDvmDex, typeIdx, clazz); 306fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom} 307fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 308fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom// Based on dvmResolveInstField/dvmResolveStaticField. 309fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic void preloadDexCachesResolveField(DvmDex* pDvmDex, uint32_t fieldIdx, bool instance) { 310fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom Field* field = dvmDexGetResolvedField(pDvmDex, fieldIdx); 311fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (field != NULL) { 312fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 313fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 314fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexFile* pDexFile = pDvmDex->pDexFile; 315fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexFieldId* pFieldId = dexGetFieldId(pDexFile, fieldIdx); 316fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom ClassObject* clazz = dvmDexGetResolvedClass(pDvmDex, pFieldId->classIdx); 317fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (clazz == NULL) { 318fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 319fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 320fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // Skip static fields for uninitialized classes because a filled 321fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // cache entry implies the class is initialized. 322fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (!instance && !dvmIsClassInitialized(clazz)) { 323fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 324fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 325fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const char* fieldName = dexStringById(pDexFile, pFieldId->nameIdx); 326fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const char* signature = dexStringByTypeIdx(pDexFile, pFieldId->typeIdx); 327fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (instance) { 328fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom field = dvmFindInstanceFieldHier(clazz, fieldName, signature); 329fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } else { 330fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom field = dvmFindStaticFieldHier(clazz, fieldName, signature); 331fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 332fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (field == NULL) { 333fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 334fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 335fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // ALOGI("VMRuntime.preloadDexCaches found field %s %s.%s", 336fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // signature, clazz->descriptor, fieldName); 337fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom dvmDexSetResolvedField(pDvmDex, fieldIdx, field); 338fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom} 339fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 340fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom// Based on dvmResolveMethod. 341fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic void preloadDexCachesResolveMethod(DvmDex* pDvmDex, 342fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom uint32_t methodIdx, 343fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom MethodType methodType) { 344fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom Method* method = dvmDexGetResolvedMethod(pDvmDex, methodIdx); 345fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (method != NULL) { 346fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 347fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 348fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexFile* pDexFile = pDvmDex->pDexFile; 349fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexMethodId* pMethodId = dexGetMethodId(pDexFile, methodIdx); 350fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom ClassObject* clazz = dvmDexGetResolvedClass(pDvmDex, pMethodId->classIdx); 351fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (clazz == NULL) { 352fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 353fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 354fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // Skip static methods for uninitialized classes because a filled 355fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // cache entry implies the class is initialized. 3568484ed554e6b52ffb7f45f8fb75ff31bda036afeBrian Carlstrom if ((methodType == METHOD_STATIC) && !dvmIsClassInitialized(clazz)) { 357fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 358fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 359fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const char* methodName = dexStringById(pDexFile, pMethodId->nameIdx); 360fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom DexProto proto; 361fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom dexProtoSetFromMethodId(&proto, pDexFile, pMethodId); 362fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 363fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (methodType == METHOD_DIRECT) { 364fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom method = dvmFindDirectMethod(clazz, methodName, &proto); 365fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } else if (methodType == METHOD_STATIC) { 366fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom method = dvmFindDirectMethodHier(clazz, methodName, &proto); 367fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } else { 368fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom method = dvmFindVirtualMethodHier(clazz, methodName, &proto); 369fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 370fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (method == NULL) { 371fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 372fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 373fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // ALOGI("VMRuntime.preloadDexCaches found method %s.%s", 374fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // clazz->descriptor, methodName); 375fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom dvmDexSetResolvedMethod(pDvmDex, methodIdx, method); 376fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom} 377fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 378fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstruct DexCacheStats { 379fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom uint32_t numStrings; 380fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom uint32_t numTypes; 381fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom uint32_t numFields; 382fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom uint32_t numMethods; 383fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom DexCacheStats() : numStrings(0), numTypes(0), numFields(0), numMethods(0) {}; 384fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom}; 385fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 386fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic const bool kPreloadDexCachesEnabled = true; 387fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 388fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom// Disabled because it takes a long time (extra half second) but 389fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom// gives almost no benefit in terms of saving private dirty pages. 390fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic const bool kPreloadDexCachesStrings = false; 391fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 392fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic const bool kPreloadDexCachesTypes = true; 393fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic const bool kPreloadDexCachesFieldsAndMethods = true; 394fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 395fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic const bool kPreloadDexCachesCollectStats = false; 396fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 397fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic void preloadDexCachesStatsTotal(DexCacheStats* total) { 398fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (!kPreloadDexCachesCollectStats) { 399fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 400fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 401fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 402fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (ClassPathEntry* cpe = gDvm.bootClassPath; cpe->kind != kCpeLastEntry; cpe++) { 403fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom DvmDex* pDvmDex = getDvmDexFromClassPathEntry(cpe); 404fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexHeader* pHeader = pDvmDex->pHeader; 405fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom total->numStrings += pHeader->stringIdsSize; 406fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom total->numFields += pHeader->fieldIdsSize; 407fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom total->numMethods += pHeader->methodIdsSize; 408fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom total->numTypes += pHeader->typeIdsSize; 409fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 410fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom} 411fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 412fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic void preloadDexCachesStatsFilled(DexCacheStats* filled) { 413fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (!kPreloadDexCachesCollectStats) { 414fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 415fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 416fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (ClassPathEntry* cpe = gDvm.bootClassPath; cpe->kind != kCpeLastEntry; cpe++) { 417fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom DvmDex* pDvmDex = getDvmDexFromClassPathEntry(cpe); 418fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexHeader* pHeader = pDvmDex->pHeader; 419fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (size_t i = 0; i < pHeader->stringIdsSize; i++) { 420fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom StringObject* string = dvmDexGetResolvedString(pDvmDex, i); 421fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (string != NULL) { 422fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom filled->numStrings++; 423fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 424fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 425fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (size_t i = 0; i < pHeader->typeIdsSize; i++) { 426fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom ClassObject* clazz = dvmDexGetResolvedClass(pDvmDex, i); 427fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (clazz != NULL) { 428fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom filled->numTypes++; 429fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 430fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 431fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (size_t i = 0; i < pHeader->fieldIdsSize; i++) { 432fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom Field* field = dvmDexGetResolvedField(pDvmDex, i); 433fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (field != NULL) { 434fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom filled->numFields++; 435fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 436fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 437fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (size_t i = 0; i < pHeader->methodIdsSize; i++) { 438fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom Method* method = dvmDexGetResolvedMethod(pDvmDex, i); 439fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (method != NULL) { 440fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom filled->numMethods++; 441fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 442fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 443fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 444fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom} 445fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 446fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstromstatic void Dalvik_dalvik_system_VMRuntime_preloadDexCaches(const u4* args, JValue* pResult) 447fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom{ 448fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (!kPreloadDexCachesEnabled) { 449fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom return; 450fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 451fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 452fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom DexCacheStats total; 453fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom DexCacheStats before; 454fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (kPreloadDexCachesCollectStats) { 455fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom ALOGI("VMRuntime.preloadDexCaches starting"); 456fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom preloadDexCachesStatsTotal(&total); 457fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom preloadDexCachesStatsFilled(&before); 458fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 459fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 460fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom // We use a std::map to avoid heap allocating StringObjects to lookup in gDvm.literalStrings 461fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom StringTable strings; 4628484ed554e6b52ffb7f45f8fb75ff31bda036afeBrian Carlstrom if (kPreloadDexCachesStrings) { 4638484ed554e6b52ffb7f45f8fb75ff31bda036afeBrian Carlstrom dvmLockMutex(&gDvm.internLock); 4648484ed554e6b52ffb7f45f8fb75ff31bda036afeBrian Carlstrom dvmHashTableLock(gDvm.literalStrings); 4658484ed554e6b52ffb7f45f8fb75ff31bda036afeBrian Carlstrom for (int i = 0; i < gDvm.literalStrings->tableSize; ++i) { 4668484ed554e6b52ffb7f45f8fb75ff31bda036afeBrian Carlstrom HashEntry *entry = &gDvm.literalStrings->pEntries[i]; 4678484ed554e6b52ffb7f45f8fb75ff31bda036afeBrian Carlstrom if (entry->data != NULL && entry->data != HASH_TOMBSTONE) { 4688484ed554e6b52ffb7f45f8fb75ff31bda036afeBrian Carlstrom preloadDexCachesStringsVisitor(&entry->data, 0, ROOT_INTERNED_STRING, &strings); 4698484ed554e6b52ffb7f45f8fb75ff31bda036afeBrian Carlstrom } 470fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 4718484ed554e6b52ffb7f45f8fb75ff31bda036afeBrian Carlstrom dvmHashTableUnlock(gDvm.literalStrings); 4728484ed554e6b52ffb7f45f8fb75ff31bda036afeBrian Carlstrom dvmUnlockMutex(&gDvm.internLock); 473fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 474fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 475fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (ClassPathEntry* cpe = gDvm.bootClassPath; cpe->kind != kCpeLastEntry; cpe++) { 476fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom DvmDex* pDvmDex = getDvmDexFromClassPathEntry(cpe); 477fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexHeader* pHeader = pDvmDex->pHeader; 478fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexFile* pDexFile = pDvmDex->pDexFile; 479fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 480fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (kPreloadDexCachesStrings) { 481fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (size_t i = 0; i < pHeader->stringIdsSize; i++) { 482fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom preloadDexCachesResolveString(pDvmDex, i, strings); 483fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 484fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 485fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 486fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (kPreloadDexCachesTypes) { 487fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (size_t i = 0; i < pHeader->typeIdsSize; i++) { 488fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom preloadDexCachesResolveType(pDvmDex, i); 489fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 490fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 491fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 492fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (kPreloadDexCachesFieldsAndMethods) { 493fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (size_t classDefIndex = 0; 494fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom classDefIndex < pHeader->classDefsSize; 495fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom classDefIndex++) { 496fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexClassDef* pClassDef = dexGetClassDef(pDexFile, classDefIndex); 497fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const u1* pEncodedData = dexGetClassData(pDexFile, pClassDef); 498fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom UniquePtr<DexClassData> pClassData(dexReadAndVerifyClassData(&pEncodedData, NULL)); 499fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (pClassData.get() == NULL) { 500fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom continue; 501fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 502fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (uint32_t fieldIndex = 0; 503fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom fieldIndex < pClassData->header.staticFieldsSize; 504fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom fieldIndex++) { 505fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexField* pField = &pClassData->staticFields[fieldIndex]; 506fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom preloadDexCachesResolveField(pDvmDex, pField->fieldIdx, false); 507fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 508fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (uint32_t fieldIndex = 0; 509fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom fieldIndex < pClassData->header.instanceFieldsSize; 510fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom fieldIndex++) { 511fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexField* pField = &pClassData->instanceFields[fieldIndex]; 512fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom preloadDexCachesResolveField(pDvmDex, pField->fieldIdx, true); 513fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 514fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (uint32_t methodIndex = 0; 515fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom methodIndex < pClassData->header.directMethodsSize; 516fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom methodIndex++) { 517fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexMethod* pDexMethod = &pClassData->directMethods[methodIndex]; 518fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom MethodType methodType = (((pDexMethod->accessFlags & ACC_STATIC) != 0) ? 519fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom METHOD_STATIC : 520fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom METHOD_DIRECT); 521fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom preloadDexCachesResolveMethod(pDvmDex, pDexMethod->methodIdx, methodType); 522fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 523fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom for (uint32_t methodIndex = 0; 524fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom methodIndex < pClassData->header.virtualMethodsSize; 525fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom methodIndex++) { 526fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom const DexMethod* pDexMethod = &pClassData->virtualMethods[methodIndex]; 527fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom preloadDexCachesResolveMethod(pDvmDex, pDexMethod->methodIdx, METHOD_VIRTUAL); 528fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 529fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 530fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 531fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 532fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 533fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom if (kPreloadDexCachesCollectStats) { 534fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom DexCacheStats after; 535fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom preloadDexCachesStatsFilled(&after); 536fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom ALOGI("VMRuntime.preloadDexCaches strings total=%d before=%d after=%d", 537fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom total.numStrings, before.numStrings, after.numStrings); 538fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom ALOGI("VMRuntime.preloadDexCaches types total=%d before=%d after=%d", 539fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom total.numTypes, before.numTypes, after.numTypes); 540fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom ALOGI("VMRuntime.preloadDexCaches fields total=%d before=%d after=%d", 541fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom total.numFields, before.numFields, after.numFields); 542fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom ALOGI("VMRuntime.preloadDexCaches methods total=%d before=%d after=%d", 543fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom total.numMethods, before.numMethods, after.numMethods); 544fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom ALOGI("VMRuntime.preloadDexCaches finished"); 545fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom } 546fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 547fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom RETURN_VOID(); 548fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom} 549fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectconst DalvikNativeMethod dvm_dalvik_system_VMRuntime[] = { 55149dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes { "addressOf", "(Ljava/lang/Object;)J", 55249dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes Dalvik_dalvik_system_VMRuntime_addressOf }, 55349dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes { "bootClassPath", "()Ljava/lang/String;", 55449dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes Dalvik_dalvik_system_VMRuntime_bootClassPath }, 55549dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes { "classPath", "()Ljava/lang/String;", 55649dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes Dalvik_dalvik_system_VMRuntime_classPath }, 55749dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes { "clearGrowthLimit", "()V", 55849dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes Dalvik_dalvik_system_VMRuntime_clearGrowthLimit }, 55949dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes { "disableJitCompilation", "()V", 56049dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes Dalvik_dalvik_system_VMRuntime_disableJitCompilation }, 561e58a9b5d443cd3fcc22abc887cf0739a4b6bc145Jesse Wilson { "isDebuggerActive", "()Z", 562e58a9b5d443cd3fcc22abc887cf0739a4b6bc145Jesse Wilson Dalvik_dalvik_system_VMRuntime_isDebuggerActive }, 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "getTargetHeapUtilization", "()F", 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Dalvik_dalvik_system_VMRuntime_getTargetHeapUtilization }, 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { "nativeSetTargetHeapUtilization", "(F)V", 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Dalvik_dalvik_system_VMRuntime_nativeSetTargetHeapUtilization }, 56749dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes { "newNonMovableArray", "(Ljava/lang/Class;I)Ljava/lang/Object;", 56849dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes Dalvik_dalvik_system_VMRuntime_newNonMovableArray }, 56949dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes { "properties", "()[Ljava/lang/String;", 57049dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes Dalvik_dalvik_system_VMRuntime_properties }, 571191a799160fe811d8558724bb86cfe543b7efc2fElliott Hughes { "setTargetSdkVersion", "(I)V", 572191a799160fe811d8558724bb86cfe543b7efc2fElliott Hughes Dalvik_dalvik_system_VMRuntime_setTargetSdkVersion }, 573a97ed1382c4e74704b44d366cf464bef5757c6b0Ben Cheng { "startJitCompilation", "()V", 574a97ed1382c4e74704b44d366cf464bef5757c6b0Ben Cheng Dalvik_dalvik_system_VMRuntime_startJitCompilation }, 57549dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes { "vmVersion", "()Ljava/lang/String;", 57649dc060d5ae9bbcc78e570ec0dd244973e920fb6Elliott Hughes Dalvik_dalvik_system_VMRuntime_vmVersion }, 577b86671d65bf4260feb2c51131dd942402b56d943Brian Carlstrom { "vmLibrary", "()Ljava/lang/String;", 578b86671d65bf4260feb2c51131dd942402b56d943Brian Carlstrom Dalvik_dalvik_system_VMRuntime_vmLibrary }, 5793086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier { "registerNativeAllocation", "(I)V", 5803086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier Dalvik_dalvik_system_VMRuntime_registerNativeAllocation }, 5813086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier { "registerNativeFree", "(I)V", 5823086ab6a9c0859af3a85d5df73d0aecc2c47ca89Mathieu Chartier Dalvik_dalvik_system_VMRuntime_registerNativeFree }, 583fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom { "preloadDexCaches", "()V", 584fe6d8fcab371be261f8d40430f5cc994c9d7e3a3Brian Carlstrom Dalvik_dalvik_system_VMRuntime_preloadDexCaches }, 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { NULL, NULL, NULL }, 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}; 587