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