Home | History | Annotate | Download | only in native
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*
     18  * dalvik.system.VMRuntime
     19  */
     20 #include "Dalvik.h"
     21 #include "ScopedPthreadMutexLock.h"
     22 #include "native/InternalNativePriv.h"
     23 
     24 #include <cutils/array.h>
     25 #include <limits.h>
     26 
     27 
     28 /*
     29  * public native float getTargetHeapUtilization()
     30  *
     31  * Gets the current ideal heap utilization, represented as a number
     32  * between zero and one.
     33  */
     34 static void Dalvik_dalvik_system_VMRuntime_getTargetHeapUtilization(
     35     const u4* args, JValue* pResult)
     36 {
     37     UNUSED_PARAMETER(args);
     38 
     39     RETURN_FLOAT(dvmGetTargetHeapUtilization());
     40 }
     41 
     42 /*
     43  * native float nativeSetTargetHeapUtilization()
     44  *
     45  * Sets the current ideal heap utilization, represented as a number
     46  * between zero and one.  Returns the old utilization.
     47  *
     48  * Note that this is NOT static.
     49  */
     50 static void Dalvik_dalvik_system_VMRuntime_nativeSetTargetHeapUtilization(
     51     const u4* args, JValue* pResult)
     52 {
     53     dvmSetTargetHeapUtilization(dvmU4ToFloat(args[1]));
     54 
     55     RETURN_VOID();
     56 }
     57 
     58 /*
     59  * public native void startJitCompilation()
     60  *
     61  * Callback function from the framework to indicate that an app has gone
     62  * through the startup phase and it is time to enable the JIT compiler.
     63  */
     64 static void Dalvik_dalvik_system_VMRuntime_startJitCompilation(const u4* args,
     65     JValue* pResult)
     66 {
     67 #if defined(WITH_JIT)
     68     if (gDvm.executionMode == kExecutionModeJit && gDvmJit.disableJit == false) {
     69         ScopedPthreadMutexLock lock(&gDvmJit.compilerLock);
     70         gDvmJit.alreadyEnabledViaFramework = true;
     71         pthread_cond_signal(&gDvmJit.compilerQueueActivity);
     72     }
     73 #endif
     74     RETURN_VOID();
     75 }
     76 
     77 /*
     78  * public native void disableJitCompilation()
     79  *
     80  * Callback function from the framework to indicate that a VM instance wants to
     81  * permanently disable the JIT compiler. Currently only the system server uses
     82  * this interface when it detects system-wide safe mode is enabled.
     83  */
     84 static void Dalvik_dalvik_system_VMRuntime_disableJitCompilation(const u4* args,
     85     JValue* pResult)
     86 {
     87 #if defined(WITH_JIT)
     88     if (gDvm.executionMode == kExecutionModeJit) {
     89         gDvmJit.disableJit = true;
     90     }
     91 #endif
     92     RETURN_VOID();
     93 }
     94 
     95 static void Dalvik_dalvik_system_VMRuntime_newNonMovableArray(const u4* args,
     96     JValue* pResult)
     97 {
     98     ClassObject* elementClass = (ClassObject*) args[1];
     99     int length = args[2];
    100 
    101     if (elementClass == NULL) {
    102         dvmThrowNullPointerException("elementClass == null");
    103         RETURN_VOID();
    104     }
    105     if (length < 0) {
    106         dvmThrowNegativeArraySizeException(length);
    107         RETURN_VOID();
    108     }
    109 
    110     // TODO: right now, we don't have a copying collector, so there's no need
    111     // to do anything special here, but we ought to pass the non-movability
    112     // through to the allocator.
    113     ClassObject* arrayClass = dvmFindArrayClassForElement(elementClass);
    114     ArrayObject* newArray = dvmAllocArrayByClass(arrayClass,
    115                                                  length,
    116                                                  ALLOC_NON_MOVING);
    117     if (newArray == NULL) {
    118         assert(dvmCheckException(dvmThreadSelf()));
    119         RETURN_VOID();
    120     }
    121     dvmReleaseTrackedAlloc((Object*) newArray, NULL);
    122 
    123     RETURN_PTR(newArray);
    124 }
    125 
    126 static void Dalvik_dalvik_system_VMRuntime_addressOf(const u4* args,
    127     JValue* pResult)
    128 {
    129     ArrayObject* array = (ArrayObject*) args[1];
    130     if (!dvmIsArray(array)) {
    131         dvmThrowIllegalArgumentException(NULL);
    132         RETURN_VOID();
    133     }
    134     // TODO: we should also check that this is a non-movable array.
    135     s8 result = (uintptr_t) array->contents;
    136     RETURN_LONG(result);
    137 }
    138 
    139 static void Dalvik_dalvik_system_VMRuntime_clearGrowthLimit(const u4* args,
    140     JValue* pResult)
    141 {
    142     dvmClearGrowthLimit();
    143     RETURN_VOID();
    144 }
    145 
    146 static void Dalvik_dalvik_system_VMRuntime_isDebuggerActive(
    147     const u4* args, JValue* pResult)
    148 {
    149     RETURN_BOOLEAN(gDvm.debuggerActive || gDvm.nativeDebuggerActive);
    150 }
    151 
    152 static void Dalvik_dalvik_system_VMRuntime_properties(const u4* args,
    153     JValue* pResult)
    154 {
    155     ArrayObject* result = dvmCreateStringArray(*gDvm.properties);
    156     dvmReleaseTrackedAlloc((Object*) result, dvmThreadSelf());
    157     RETURN_PTR(result);
    158 }
    159 
    160 static void returnCString(JValue* pResult, const char* s)
    161 {
    162     Object* result = (Object*) dvmCreateStringFromCstr(s);
    163     dvmReleaseTrackedAlloc(result, dvmThreadSelf());
    164     RETURN_PTR(result);
    165 }
    166 
    167 static void Dalvik_dalvik_system_VMRuntime_bootClassPath(const u4* args,
    168     JValue* pResult)
    169 {
    170     returnCString(pResult, gDvm.bootClassPathStr);
    171 }
    172 
    173 static void Dalvik_dalvik_system_VMRuntime_classPath(const u4* args,
    174     JValue* pResult)
    175 {
    176     returnCString(pResult, gDvm.classPathStr);
    177 }
    178 
    179 static void Dalvik_dalvik_system_VMRuntime_vmVersion(const u4* args,
    180     JValue* pResult)
    181 {
    182     char buf[64];
    183     sprintf(buf, "%d.%d.%d",
    184             DALVIK_MAJOR_VERSION, DALVIK_MINOR_VERSION, DALVIK_BUG_VERSION);
    185     returnCString(pResult, buf);
    186 }
    187 
    188 static void Dalvik_dalvik_system_VMRuntime_setTargetSdkVersion(const u4* args,
    189     JValue* pResult)
    190 {
    191     // This is the target SDK version of the app we're about to run.
    192     // Note that this value may be CUR_DEVELOPMENT (10000).
    193     // Note that this value may be 0, meaning "current".
    194     int targetSdkVersion = args[1];
    195     if (targetSdkVersion > 0 && targetSdkVersion <= 13 /* honeycomb-mr2 */) {
    196         // TODO: running with CheckJNI should override this and force you to obey the strictest rules.
    197         ALOGI("Turning on JNI app bug workarounds for target SDK version %i...", targetSdkVersion);
    198         gDvmJni.workAroundAppJniBugs = true;
    199     }
    200     RETURN_VOID();
    201 }
    202 
    203 const DalvikNativeMethod dvm_dalvik_system_VMRuntime[] = {
    204     { "addressOf", "(Ljava/lang/Object;)J",
    205         Dalvik_dalvik_system_VMRuntime_addressOf },
    206     { "bootClassPath", "()Ljava/lang/String;",
    207         Dalvik_dalvik_system_VMRuntime_bootClassPath },
    208     { "classPath", "()Ljava/lang/String;",
    209         Dalvik_dalvik_system_VMRuntime_classPath },
    210     { "clearGrowthLimit", "()V",
    211         Dalvik_dalvik_system_VMRuntime_clearGrowthLimit },
    212     { "disableJitCompilation", "()V",
    213         Dalvik_dalvik_system_VMRuntime_disableJitCompilation },
    214     { "isDebuggerActive", "()Z",
    215         Dalvik_dalvik_system_VMRuntime_isDebuggerActive },
    216     { "getTargetHeapUtilization", "()F",
    217         Dalvik_dalvik_system_VMRuntime_getTargetHeapUtilization },
    218     { "nativeSetTargetHeapUtilization", "(F)V",
    219         Dalvik_dalvik_system_VMRuntime_nativeSetTargetHeapUtilization },
    220     { "newNonMovableArray", "(Ljava/lang/Class;I)Ljava/lang/Object;",
    221         Dalvik_dalvik_system_VMRuntime_newNonMovableArray },
    222     { "properties", "()[Ljava/lang/String;",
    223         Dalvik_dalvik_system_VMRuntime_properties },
    224     { "setTargetSdkVersion", "(I)V",
    225         Dalvik_dalvik_system_VMRuntime_setTargetSdkVersion },
    226     { "startJitCompilation", "()V",
    227         Dalvik_dalvik_system_VMRuntime_startJitCompilation },
    228     { "vmVersion", "()Ljava/lang/String;",
    229         Dalvik_dalvik_system_VMRuntime_vmVersion },
    230     { NULL, NULL, NULL },
    231 };
    232