Home | History | Annotate | Download | only in system
      1 /*
      2  * Copyright (C) 2007 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 package dalvik.system;
     18 
     19 import java.util.HashMap;
     20 import java.util.Map;
     21 
     22 /**
     23  * Provides an interface to VM-global, Dalvik-specific features.
     24  * An application cannot create its own Runtime instance, and must obtain
     25  * one from the getRuntime method.
     26  *
     27  * @hide
     28  */
     29 public final class VMRuntime {
     30 
     31     /**
     32      * Holds the VMRuntime singleton.
     33      */
     34     private static final VMRuntime THE_ONE = new VMRuntime();
     35 
     36     private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP
     37             = new HashMap<String, String>();
     38     static {
     39         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi", "arm");
     40         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi-v7a", "arm");
     41         ABI_TO_INSTRUCTION_SET_MAP.put("mips", "mips");
     42         ABI_TO_INSTRUCTION_SET_MAP.put("mips64", "mips64");
     43         ABI_TO_INSTRUCTION_SET_MAP.put("x86", "x86");
     44         ABI_TO_INSTRUCTION_SET_MAP.put("x86_64", "x86_64");
     45         ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a", "arm64");
     46     }
     47 
     48     private int targetSdkVersion;
     49 
     50     /**
     51      * Prevents this class from being instantiated.
     52      */
     53     private VMRuntime() {
     54     }
     55 
     56     /**
     57      * Returns the object that represents the VM instance's Dalvik-specific
     58      * runtime environment.
     59      *
     60      * @return the runtime object
     61      */
     62     public static VMRuntime getRuntime() {
     63         return THE_ONE;
     64     }
     65 
     66     /**
     67      * Returns a copy of the VM's command-line property settings.
     68      * These are in the form "name=value" rather than "-Dname=value".
     69      */
     70     public native String[] properties();
     71 
     72     /**
     73      * Returns the VM's boot class path.
     74      */
     75     public native String bootClassPath();
     76 
     77     /**
     78      * Returns the VM's class path.
     79      */
     80     public native String classPath();
     81 
     82     /**
     83      * Returns the VM's version.
     84      */
     85     public native String vmVersion();
     86 
     87     /**
     88      * Returns the name of the shared library providing the VM implementation.
     89      */
     90     public native String vmLibrary();
     91 
     92     /**
     93      * Returns the VM's instruction set.
     94      */
     95     public native String vmInstructionSet();
     96 
     97     /**
     98      * Returns whether the VM is running in 64-bit mode.
     99      */
    100     public native boolean is64Bit();
    101 
    102     /**
    103      * Returns whether the VM is running with JNI checking enabled.
    104      */
    105     public native boolean isCheckJniEnabled();
    106 
    107     /**
    108      * Gets the current ideal heap utilization, represented as a number
    109      * between zero and one.  After a GC happens, the Dalvik heap may
    110      * be resized so that (size of live objects) / (size of heap) is
    111      * equal to this number.
    112      *
    113      * @return the current ideal heap utilization
    114      */
    115     public native float getTargetHeapUtilization();
    116 
    117     /**
    118      * Sets the current ideal heap utilization, represented as a number
    119      * between zero and one.  After a GC happens, the Dalvik heap may
    120      * be resized so that (size of live objects) / (size of heap) is
    121      * equal to this number.
    122      *
    123      * <p>This is only a hint to the garbage collector and may be ignored.
    124      *
    125      * @param newTarget the new suggested ideal heap utilization.
    126      *                  This value may be adjusted internally.
    127      * @return the previous ideal heap utilization
    128      * @throws IllegalArgumentException if newTarget is &lt;= 0.0 or &gt;= 1.0
    129      */
    130     public float setTargetHeapUtilization(float newTarget) {
    131         if (newTarget <= 0.0f || newTarget >= 1.0f) {
    132             throw new IllegalArgumentException(newTarget +
    133                     " out of range (0,1)");
    134         }
    135         /* Synchronize to make sure that only one thread gets
    136          * a given "old" value if both update at the same time.
    137          * Allows for reliable save-and-restore semantics.
    138          */
    139         synchronized (this) {
    140             float oldTarget = getTargetHeapUtilization();
    141             nativeSetTargetHeapUtilization(newTarget);
    142             return oldTarget;
    143         }
    144     }
    145 
    146     /**
    147      * Sets the target SDK version. Should only be called before the
    148      * app starts to run, because it may change the VM's behavior in
    149      * dangerous ways. Use 0 to mean "current" (since callers won't
    150      * necessarily know the actual current SDK version, and the
    151      * allocated version numbers start at 1), and 10000 to mean
    152      * CUR_DEVELOPMENT.
    153      */
    154     public synchronized void setTargetSdkVersion(int targetSdkVersion) {
    155         this.targetSdkVersion = targetSdkVersion;
    156         setTargetSdkVersionNative(this.targetSdkVersion);
    157     }
    158 
    159     /**
    160      * Gets the target SDK version. See {@link #setTargetSdkVersion} for
    161      * special values.
    162      */
    163     public synchronized int getTargetSdkVersion() {
    164         return targetSdkVersion;
    165     }
    166 
    167     private native void setTargetSdkVersionNative(int targetSdkVersion);
    168 
    169     /**
    170      * This method exists for binary compatibility.  It was part of a
    171      * heap sizing API which was removed in Android 3.0 (Honeycomb).
    172      */
    173     @Deprecated
    174     public long getMinimumHeapSize() {
    175         return 0;
    176     }
    177 
    178     /**
    179      * This method exists for binary compatibility.  It was part of a
    180      * heap sizing API which was removed in Android 3.0 (Honeycomb).
    181      */
    182     @Deprecated
    183     public long setMinimumHeapSize(long size) {
    184         return 0;
    185     }
    186 
    187     /**
    188      * This method exists for binary compatibility.  It used to
    189      * perform a garbage collection that cleared SoftReferences.
    190      */
    191     @Deprecated
    192     public void gcSoftReferences() {}
    193 
    194     /**
    195      * This method exists for binary compatibility.  It is equivalent
    196      * to {@link System#runFinalization}.
    197      */
    198     @Deprecated
    199     public void runFinalizationSync() {
    200         System.runFinalization();
    201     }
    202 
    203     /**
    204      * Implements setTargetHeapUtilization().
    205      *
    206      * @param newTarget the new suggested ideal heap utilization.
    207      *                  This value may be adjusted internally.
    208      */
    209     private native void nativeSetTargetHeapUtilization(float newTarget);
    210 
    211     /**
    212      * This method exists for binary compatibility.  It was part of
    213      * the external allocation API which was removed in Android 3.0 (Honeycomb).
    214      */
    215     @Deprecated
    216     public boolean trackExternalAllocation(long size) {
    217         return true;
    218     }
    219 
    220     /**
    221      * This method exists for binary compatibility.  It was part of
    222      * the external allocation API which was removed in Android 3.0 (Honeycomb).
    223      */
    224     @Deprecated
    225     public void trackExternalFree(long size) {}
    226 
    227     /**
    228      * This method exists for binary compatibility.  It was part of
    229      * the external allocation API which was removed in Android 3.0 (Honeycomb).
    230      */
    231     @Deprecated
    232     public long getExternalBytesAllocated() {
    233         return 0;
    234     }
    235 
    236     /**
    237      * Tells the VM to enable the JIT compiler. If the VM does not have a JIT
    238      * implementation, calling this method should have no effect.
    239      */
    240     public native void startJitCompilation();
    241 
    242     /**
    243      * Tells the VM to disable the JIT compiler. If the VM does not have a JIT
    244      * implementation, calling this method should have no effect.
    245      */
    246     public native void disableJitCompilation();
    247 
    248     /**
    249      * Returns an array allocated in an area of the Java heap where it will never be moved.
    250      * This is used to implement native allocations on the Java heap, such as DirectByteBuffers
    251      * and Bitmaps.
    252      */
    253     public native Object newNonMovableArray(Class<?> componentType, int length);
    254 
    255     /**
    256      * Returns an array of at least minLength, but potentially larger. The increased size comes from
    257      * avoiding any padding after the array. The amount of padding varies depending on the
    258      * componentType and the memory allocator implementation.
    259      */
    260     public native Object newUnpaddedArray(Class<?> componentType, int minLength);
    261 
    262     /**
    263      * Returns the address of array[0]. This differs from using JNI in that JNI might lie and
    264      * give you the address of a copy of the array when in forcecopy mode.
    265      */
    266     public native long addressOf(Object array);
    267 
    268     /**
    269      * Removes any growth limits, allowing the application to allocate
    270      * up to the maximum heap size.
    271      */
    272     public native void clearGrowthLimit();
    273 
    274     /**
    275      * Returns true if either a Java debugger or native debugger is active.
    276      */
    277     public native boolean isDebuggerActive();
    278 
    279     /**
    280      * Registers a native allocation so that the heap knows about it and performs GC as required.
    281      * If the number of native allocated bytes exceeds the native allocation watermark, the
    282      * function requests a concurrent GC. If the native bytes allocated exceeds a second higher
    283      * watermark, it is determined that the application is registering native allocations at an
    284      * unusually high rate and a GC is performed inside of the function to prevent memory usage
    285      * from excessively increasing.
    286      */
    287     public native void registerNativeAllocation(int bytes);
    288 
    289     /**
    290      * Registers a native free by reducing the number of native bytes accounted for.
    291      */
    292     public native void registerNativeFree(int bytes);
    293 
    294     public native void trimHeap();
    295     public native void concurrentGC();
    296 
    297     /**
    298      * Let the heap know of the new process state. This can change allocation and garbage collection
    299      * behavior regarding trimming and compaction.
    300      */
    301     public native void updateProcessState(int state);
    302 
    303     /**
    304      * Fill in dex caches with classes, fields, and methods that are
    305      * already loaded. Typically used after Zygote preloading.
    306      */
    307     public native void preloadDexCaches();
    308 
    309     /**
    310      * Register application info
    311      */
    312     public static native void registerAppInfo(String appDir, String processName, String pkgname);
    313 
    314     /**
    315      * Returns the runtime instruction set corresponding to a given ABI. Multiple
    316      * compatible ABIs might map to the same instruction set. For example
    317      * {@code armeabi-v7a} and {@code armeabi} might map to the instruction set {@code arm}.
    318      *
    319      * This influences the compilation of the applications classes.
    320      */
    321     public static String getInstructionSet(String abi) {
    322         final String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi);
    323         if (instructionSet == null) {
    324             throw new IllegalArgumentException("Unsupported ABI: " + abi);
    325         }
    326 
    327         return instructionSet;
    328     }
    329 
    330     public static boolean is64BitInstructionSet(String instructionSet) {
    331         return "arm64".equals(instructionSet) ||
    332                 "x86_64".equals(instructionSet) ||
    333                 "mips64".equals(instructionSet);
    334     }
    335 
    336     public static boolean is64BitAbi(String abi) {
    337         return is64BitInstructionSet(getInstructionSet(abi));
    338     }
    339 
    340     /**
    341      * Return false if the boot class path for the given instruction
    342      * set mapped from disk storage, versus being interpretted from
    343      * dirty pages in memory.
    344      */
    345     public static native boolean isBootClassPathOnDisk(String instructionSet);
    346 
    347     /**
    348      * Returns the instruction set of the current runtime.
    349      */
    350     public static native String getCurrentInstructionSet();
    351 
    352 }
    353