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 dalvik.annotation.optimization.FastNative;
     20 import java.lang.ref.FinalizerReference;
     21 import java.util.HashMap;
     22 import java.util.Map;
     23 
     24 /**
     25  * Provides an interface to VM-global, Dalvik-specific features.
     26  * An application cannot create its own Runtime instance, and must obtain
     27  * one from the getRuntime method.
     28  *
     29  * @hide
     30  */
     31 public final class VMRuntime {
     32 
     33     /**
     34      * Holds the VMRuntime singleton.
     35      */
     36     private static final VMRuntime THE_ONE = new VMRuntime();
     37 
     38     // Note: Instruction set names are used to construct the names of some
     39     // system properties. To be sure that the properties stay valid the
     40     // instruction set name should not exceed 7 characters. See installd
     41     // and the package manager for the actual propeties.
     42     private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP
     43             = new HashMap<String, String>(16);
     44     static {
     45         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi", "arm");
     46         ABI_TO_INSTRUCTION_SET_MAP.put("armeabi-v7a", "arm");
     47         ABI_TO_INSTRUCTION_SET_MAP.put("mips", "mips");
     48         ABI_TO_INSTRUCTION_SET_MAP.put("mips64", "mips64");
     49         ABI_TO_INSTRUCTION_SET_MAP.put("x86", "x86");
     50         ABI_TO_INSTRUCTION_SET_MAP.put("x86_64", "x86_64");
     51         ABI_TO_INSTRUCTION_SET_MAP.put("arm64-v8a", "arm64");
     52     }
     53 
     54     /**
     55      * Magic version number for a current development build, which has not
     56      * yet turned into an official release. This number must be larger than
     57      * any released version in {@code android.os.Build.VERSION_CODES}.
     58      * @hide
     59      */
     60     public static final int SDK_VERSION_CUR_DEVELOPMENT = 10000;
     61 
     62     private int targetSdkVersion = SDK_VERSION_CUR_DEVELOPMENT;
     63 
     64     /**
     65      * Prevents this class from being instantiated.
     66      */
     67     private VMRuntime() {
     68     }
     69 
     70     /**
     71      * Returns the object that represents the VM instance's Dalvik-specific
     72      * runtime environment.
     73      *
     74      * @return the runtime object
     75      */
     76     public static VMRuntime getRuntime() {
     77         return THE_ONE;
     78     }
     79 
     80     /**
     81      * Returns a copy of the VM's command-line property settings.
     82      * These are in the form "name=value" rather than "-Dname=value".
     83      */
     84     public native String[] properties();
     85 
     86     /**
     87      * Returns the VM's boot class path.
     88      */
     89     public native String bootClassPath();
     90 
     91     /**
     92      * Returns the VM's class path.
     93      */
     94     public native String classPath();
     95 
     96     /**
     97      * Returns the VM's version.
     98      */
     99     public native String vmVersion();
    100 
    101     /**
    102      * Returns the name of the shared library providing the VM implementation.
    103      */
    104     public native String vmLibrary();
    105 
    106     /**
    107      * Returns the VM's instruction set.
    108      */
    109     public native String vmInstructionSet();
    110 
    111     /**
    112      * Returns whether the VM is running in 64-bit mode.
    113      */
    114     @FastNative
    115     public native boolean is64Bit();
    116 
    117     /**
    118      * Returns whether the VM is running with JNI checking enabled.
    119      */
    120     @FastNative
    121     public native boolean isCheckJniEnabled();
    122 
    123     /**
    124      * Gets the current ideal heap utilization, represented as a number
    125      * between zero and one.  After a GC happens, the Dalvik heap may
    126      * be resized so that (size of live objects) / (size of heap) is
    127      * equal to this number.
    128      *
    129      * @return the current ideal heap utilization
    130      */
    131     public native float getTargetHeapUtilization();
    132 
    133     /**
    134      * Sets the current ideal heap utilization, represented as a number
    135      * between zero and one.  After a GC happens, the Dalvik heap may
    136      * be resized so that (size of live objects) / (size of heap) is
    137      * equal to this number.
    138      *
    139      * <p>This is only a hint to the garbage collector and may be ignored.
    140      *
    141      * @param newTarget the new suggested ideal heap utilization.
    142      *                  This value may be adjusted internally.
    143      * @return the previous ideal heap utilization
    144      * @throws IllegalArgumentException if newTarget is &lt;= 0.0 or &gt;= 1.0
    145      */
    146     public float setTargetHeapUtilization(float newTarget) {
    147         if (newTarget <= 0.0f || newTarget >= 1.0f) {
    148             throw new IllegalArgumentException(newTarget +
    149                     " out of range (0,1)");
    150         }
    151         /* Synchronize to make sure that only one thread gets
    152          * a given "old" value if both update at the same time.
    153          * Allows for reliable save-and-restore semantics.
    154          */
    155         synchronized (this) {
    156             float oldTarget = getTargetHeapUtilization();
    157             nativeSetTargetHeapUtilization(newTarget);
    158             return oldTarget;
    159         }
    160     }
    161 
    162     /**
    163      * Sets the target SDK version. Should only be called before the
    164      * app starts to run, because it may change the VM's behavior in
    165      * dangerous ways. Defaults to {@link #SDK_VERSION_CUR_DEVELOPMENT}.
    166      */
    167     public synchronized void setTargetSdkVersion(int targetSdkVersion) {
    168         this.targetSdkVersion = targetSdkVersion;
    169         setTargetSdkVersionNative(this.targetSdkVersion);
    170     }
    171 
    172     /**
    173      * Gets the target SDK version. See {@link #setTargetSdkVersion} for
    174      * special values.
    175      */
    176     public synchronized int getTargetSdkVersion() {
    177         return targetSdkVersion;
    178     }
    179 
    180     private native void setTargetSdkVersionNative(int targetSdkVersion);
    181 
    182     /**
    183      * This method exists for binary compatibility.  It was part of a
    184      * heap sizing API which was removed in Android 3.0 (Honeycomb).
    185      */
    186     @Deprecated
    187     public long getMinimumHeapSize() {
    188         return 0;
    189     }
    190 
    191     /**
    192      * This method exists for binary compatibility.  It was part of a
    193      * heap sizing API which was removed in Android 3.0 (Honeycomb).
    194      */
    195     @Deprecated
    196     public long setMinimumHeapSize(long size) {
    197         return 0;
    198     }
    199 
    200     /**
    201      * This method exists for binary compatibility.  It used to
    202      * perform a garbage collection that cleared SoftReferences.
    203      */
    204     @Deprecated
    205     public void gcSoftReferences() {}
    206 
    207     /**
    208      * This method exists for binary compatibility.  It is equivalent
    209      * to {@link System#runFinalization}.
    210      */
    211     @Deprecated
    212     public void runFinalizationSync() {
    213         System.runFinalization();
    214     }
    215 
    216     /**
    217      * Implements setTargetHeapUtilization().
    218      *
    219      * @param newTarget the new suggested ideal heap utilization.
    220      *                  This value may be adjusted internally.
    221      */
    222     private native void nativeSetTargetHeapUtilization(float newTarget);
    223 
    224     /**
    225      * This method exists for binary compatibility.  It was part of
    226      * the external allocation API which was removed in Android 3.0 (Honeycomb).
    227      */
    228     @Deprecated
    229     public boolean trackExternalAllocation(long size) {
    230         return true;
    231     }
    232 
    233     /**
    234      * This method exists for binary compatibility.  It was part of
    235      * the external allocation API which was removed in Android 3.0 (Honeycomb).
    236      */
    237     @Deprecated
    238     public void trackExternalFree(long size) {}
    239 
    240     /**
    241      * This method exists for binary compatibility.  It was part of
    242      * the external allocation API which was removed in Android 3.0 (Honeycomb).
    243      */
    244     @Deprecated
    245     public long getExternalBytesAllocated() {
    246         return 0;
    247     }
    248 
    249     /**
    250      * Tells the VM to enable the JIT compiler. If the VM does not have a JIT
    251      * implementation, calling this method should have no effect.
    252      */
    253     public native void startJitCompilation();
    254 
    255     /**
    256      * Tells the VM to disable the JIT compiler. If the VM does not have a JIT
    257      * implementation, calling this method should have no effect.
    258      */
    259     public native void disableJitCompilation();
    260 
    261     /**
    262      * Returns an array allocated in an area of the Java heap where it will never be moved.
    263      * This is used to implement native allocations on the Java heap, such as DirectByteBuffers
    264      * and Bitmaps.
    265      */
    266     @FastNative
    267     public native Object newNonMovableArray(Class<?> componentType, int length);
    268 
    269     /**
    270      * Returns an array of at least minLength, but potentially larger. The increased size comes from
    271      * avoiding any padding after the array. The amount of padding varies depending on the
    272      * componentType and the memory allocator implementation.
    273      */
    274     @FastNative
    275     public native Object newUnpaddedArray(Class<?> componentType, int minLength);
    276 
    277     /**
    278      * Returns the address of array[0]. This differs from using JNI in that JNI might lie and
    279      * give you the address of a copy of the array when in forcecopy mode.
    280      */
    281     @FastNative
    282     public native long addressOf(Object array);
    283 
    284     /**
    285      * Removes any growth limits, allowing the application to allocate
    286      * up to the maximum heap size.
    287      */
    288     public native void clearGrowthLimit();
    289 
    290     /**
    291      * Make the current growth limit the new non growth limit capacity by releasing pages which
    292      * are after the growth limit but before the non growth limit capacity.
    293      */
    294     public native void clampGrowthLimit();
    295 
    296     /**
    297      * Returns true if either a Java debugger or native debugger is active.
    298      */
    299     @FastNative
    300     public native boolean isDebuggerActive();
    301 
    302     /**
    303      * Returns true if native debugging is on.
    304      */
    305     @FastNative
    306     public native boolean isNativeDebuggable();
    307 
    308     /**
    309      * Registers a native allocation so that the heap knows about it and performs GC as required.
    310      * If the number of native allocated bytes exceeds the native allocation watermark, the
    311      * function requests a concurrent GC. If the native bytes allocated exceeds a second higher
    312      * watermark, it is determined that the application is registering native allocations at an
    313      * unusually high rate and a GC is performed inside of the function to prevent memory usage
    314      * from excessively increasing.
    315      */
    316     public native void registerNativeAllocation(int bytes);
    317 
    318     /**
    319      * Registers a native free by reducing the number of native bytes accounted for.
    320      */
    321     public native void registerNativeFree(int bytes);
    322 
    323     /**
    324      * Wait for objects to be finalized.
    325      *
    326      * If finalization takes longer than timeout, then the function returns before all objects are
    327      * finalized.
    328      *
    329      * @param timeout
    330      *            timeout in nanoseconds of the maximum time to wait until all pending finalizers
    331      *            are run. If timeout is 0, then there is no timeout. Note that the timeout does
    332      *            not stop the finalization process, it merely stops the wait.
    333      *
    334      * @see #Runtime.runFinalization()
    335      * @see #wait(long,int)
    336      */
    337     public static void runFinalization(long timeout) {
    338         try {
    339             FinalizerReference.finalizeAllEnqueued(timeout);
    340         } catch (InterruptedException e) {
    341             // Interrupt the current thread without actually throwing the InterruptionException
    342             // for the caller.
    343             Thread.currentThread().interrupt();
    344         }
    345     }
    346 
    347     public native void requestConcurrentGC();
    348     public native void concurrentGC();
    349     public native void requestHeapTrim();
    350     public native void trimHeap();
    351     public native void startHeapTaskProcessor();
    352     public native void stopHeapTaskProcessor();
    353     public native void runHeapTasks();
    354 
    355     /**
    356      * Let the heap know of the new process state. This can change allocation and garbage collection
    357      * behavior regarding trimming and compaction.
    358      */
    359     public native void updateProcessState(int state);
    360 
    361     /**
    362      * Fill in dex caches with classes, fields, and methods that are
    363      * already loaded. Typically used after Zygote preloading.
    364      */
    365     public native void preloadDexCaches();
    366 
    367     /**
    368      * Register application info.
    369      * @param profileFile the path of the file where the profile information should be stored.
    370      * @param codePaths the code paths that should be profiled.
    371      */
    372     public static native void registerAppInfo(String profileFile, String[] codePaths);
    373 
    374     /**
    375      * Returns the runtime instruction set corresponding to a given ABI. Multiple
    376      * compatible ABIs might map to the same instruction set. For example
    377      * {@code armeabi-v7a} and {@code armeabi} might map to the instruction set {@code arm}.
    378      *
    379      * This influences the compilation of the applications classes.
    380      */
    381     public static String getInstructionSet(String abi) {
    382         final String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi);
    383         if (instructionSet == null) {
    384             throw new IllegalArgumentException("Unsupported ABI: " + abi);
    385         }
    386 
    387         return instructionSet;
    388     }
    389 
    390     public static boolean is64BitInstructionSet(String instructionSet) {
    391         return "arm64".equals(instructionSet) ||
    392                 "x86_64".equals(instructionSet) ||
    393                 "mips64".equals(instructionSet);
    394     }
    395 
    396     public static boolean is64BitAbi(String abi) {
    397         return is64BitInstructionSet(getInstructionSet(abi));
    398     }
    399 
    400     /**
    401      * Return false if the boot class path for the given instruction
    402      * set mapped from disk storage, versus being interpretted from
    403      * dirty pages in memory.
    404      */
    405     public static native boolean isBootClassPathOnDisk(String instructionSet);
    406 
    407     /**
    408      * Returns the instruction set of the current runtime.
    409      */
    410     public static native String getCurrentInstructionSet();
    411 
    412     /**
    413      * Return true if the dalvik cache was pruned when booting. This may have happened for
    414      * various reasons, e.g., after an OTA. The return value is for the current instruction
    415      * set.
    416      */
    417     public static native boolean didPruneDalvikCache();
    418 
    419     /**
    420      * Register the current execution thread to the runtime as sensitive thread.
    421      * Should be called just once. Subsequent calls are ignored.
    422      */
    423     public static native void registerSensitiveThread();
    424 
    425     /**
    426      * Sets up the priority of the system daemon thread (caller).
    427      */
    428     public static native void setSystemDaemonThreadPriority();
    429 }
    430