/*
 * static boolean isDebuggingEnabled()
 *
 * Returns "true" if debugging is enabled.
 */
static void Dalvik_dalvik_system_VMDebug_isDebuggingEnabled(const u4* args,
    JValue* pResult)
{
    UNUSED_PARAMETER(args);

    RETURN_BOOLEAN(gDvm.jdwpConfigured);
}
/*
 * static boolean isDebuggerConnected()
 *
 * Returns "true" if a debugger is attached.
 */
static void Dalvik_dalvik_system_VMDebug_isDebuggerConnected(const u4* args,
    JValue* pResult)
{
    UNUSED_PARAMETER(args);

    RETURN_BOOLEAN(dvmDbgIsDebuggerConnected());
}
/*
 * public static boolean getRecentAllocationStatus()
 *
 * Returns "true" if allocation tracking is enabled.
 */
static void
    Dalvik_org_apache_harmony_dalvik_ddmc_DdmVmInternal_getRecentAllocationStatus(
    const u4* args, JValue* pResult)
{
    UNUSED_PARAMETER(args);
    RETURN_BOOLEAN(gDvm.allocRecords != NULL);
}
예제 #4
0
/*
 * public static native boolean isInvoke(int opcode);
 */
static void Dalvik_dalvik_bytecode_OpcodeInfo_isInvoke(const u4 *args,
                                                       JValue *pResult) {
    Opcode opcode = static_cast<Opcode>(args[0]);
    int flags = dexGetFlagsFromOpcode(opcode);
    bool result = (flags & kInstrInvoke) != 0;
    RETURN_BOOLEAN(result);
}
예제 #5
0
/*
 * static boolean isMethodTracingActive()
 *
 * Determine whether method tracing is currently active.
 */
static void Dalvik_dalvik_system_VMDebug_isMethodTracingActive(const u4* args,
    JValue* pResult)
{
    UNUSED_PARAMETER(args);

    RETURN_BOOLEAN(dvmIsMethodTraceActive());
}
/*
 * public static int heapInfoNotify(int what)
 *
 * Enable DDM heap notifications.
 */
static void Dalvik_org_apache_harmony_dalvik_ddmc_DdmVmInternal_heapInfoNotify(
    const u4* args, JValue* pResult)
{
    int when = args[0];
    bool ret;

    ret = dvmDdmHandleHpifChunk(when);
    RETURN_BOOLEAN(ret);
}
/*
 * static boolean isAnnotationPresent(
 *         Class declaringClass, int slot, Class annotationType);
 */
static void Dalvik_java_lang_reflect_Method_isAnnotationPresent(const u4* args,
    JValue* pResult)
{
    ClassObject* clazz = (ClassObject*) args[0];
    int slot = args[1];
    ClassObject* annotationClazz = (ClassObject*) args[2];

    Method* meth = dvmSlotToMethod(clazz, slot);
    RETURN_BOOLEAN(dvmIsMethodAnnotationPresent(clazz, meth, annotationClazz));
}
/*
 * public static boolean heapSegmentNotify(int when, int what, bool native)
 *
 * Enable DDM heap notifications.
 */
static void
    Dalvik_org_apache_harmony_dalvik_ddmc_DdmVmInternal_heapSegmentNotify(
    const u4* args, JValue* pResult)
{
    int  when   = args[0];        // 0=never (off), 1=during GC
    int  what   = args[1];        // 0=merged objects, 1=distinct objects
    bool native = (args[2] != 0); // false=virtual heap, true=native heap
    bool ret;

    ret = dvmDdmHandleHpsgNhsgChunk(when, what, native);
    RETURN_BOOLEAN(ret);
}
예제 #9
0
/*
 * static boolean interrupted()
 *
 * Determine if the current thread has been interrupted.  Clears the flag.
 */
static void Dalvik_java_lang_VMThread_interrupted(const u4* args,
    JValue* pResult)
{
    Thread* self = dvmThreadSelf();
    bool interrupted;

    UNUSED_PARAMETER(args);

    interrupted = self->interrupted;
    self->interrupted = false;
    RETURN_BOOLEAN(interrupted);
}
예제 #10
0
/*
 * public native boolean compareAndSwapInt(Object obj, long offset,
 *         int expectedValue, int newValue);
 */
static void Dalvik_sun_misc_Unsafe_compareAndSwapInt(const u4 *args,
                                                     JValue *pResult) {
    // We ignore the this pointer in args[0].
    Object *obj = (Object *) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s4 expectedValue = args[4];
    s4 newValue = args[5];
    volatile int32_t *address = (volatile int32_t *) (((u1 *) obj) + offset);

    // Note: android_atomic_release_cas() returns 0 on success, not failure.
    int result = android_atomic_release_cas(expectedValue, newValue, address);

    RETURN_BOOLEAN(result == 0);
}
예제 #11
0
/*
 * public native boolean compareAndSwapLong(Object obj, long offset,
 *         long expectedValue, long newValue);
 */
static void Dalvik_sun_misc_Unsafe_compareAndSwapLong(const u4 *args,
                                                      JValue *pResult) {
    // We ignore the this pointer in args[0].
    Object *obj = (Object *) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    s8 expectedValue = GET_ARG_LONG(args, 4);
    s8 newValue = GET_ARG_LONG(args, 6);
    volatile int64_t *address = (volatile int64_t *) (((u1 *) obj) + offset);

    // Note: android_atomic_cmpxchg() returns 0 on success, not failure.
    int result =
            dvmQuasiAtomicCas64(expectedValue, newValue, address);

    RETURN_BOOLEAN(result == 0);
}
예제 #12
0
/*
 * public native boolean compareAndSwapObject(Object obj, long offset,
 *         Object expectedValue, Object newValue);
 */
static void Dalvik_sun_misc_Unsafe_compareAndSwapObject(const u4 *args,
                                                        JValue *pResult) {
    // We ignore the this pointer in args[0].
    Object *obj = (Object *) args[1];
    s8 offset = GET_ARG_LONG(args, 2);
    Object *expectedValue = (Object *) args[4];
    Object *newValue = (Object *) args[5];
    int32_t *address = (int32_t *) (((u1 *) obj) + offset);

    // Note: android_atomic_cmpxchg() returns 0 on success, not failure.
    int result = android_atomic_release_cas((int32_t) expectedValue,
                                            (int32_t) newValue, address);
    dvmWriteBarrierField(obj, address);
    RETURN_BOOLEAN(result == 0);
}
/*
 * public static boolean isDexOptNeeded(String apkName)
 *         throws FileNotFoundException, IOException
 *
 * Returns true if the VM believes that the apk/jar file is out of date
 * and should be passed through "dexopt" again.
 *
 * @param fileName the absolute path to the apk/jar file to examine.
 * @return true if dexopt should be called on the file, false otherwise.
 * @throws java.io.FileNotFoundException if fileName is not readable,
 *         not a file, or not present.
 * @throws java.io.IOException if fileName is not a valid apk/jar file or
 *         if problems occur while parsing it.
 * @throws java.lang.NullPointerException if fileName is null.
 * @throws dalvik.system.StaleDexCacheError if the optimized dex file
 *         is stale but exists on a read-only partition.
 */
static void Dalvik_dalvik_system_DexFile_isDexOptNeeded(const u4* args,
    JValue* pResult)
{
    StringObject* nameObj = (StringObject*) args[0];
    char* name;
    DexCacheStatus status;
    int result;

    name = dvmCreateCstrFromString(nameObj);
    if (name == NULL) {
        dvmThrowException("Ljava/lang/NullPointerException;", NULL);
        RETURN_VOID();
    }
    if (access(name, R_OK) != 0) {
        dvmThrowException("Ljava/io/FileNotFoundException;", name);
        free(name);
        RETURN_VOID();
    }
    status = dvmDexCacheStatus(name);
    LOGV("dvmDexCacheStatus(%s) returned %d\n", name, status);

    result = true;
    switch (status) {
    default: //FALLTHROUGH
    case DEX_CACHE_BAD_ARCHIVE:
        dvmThrowException("Ljava/io/IOException;", name);
        result = -1;
        break;
    case DEX_CACHE_OK:
        result = false;
        break;
    case DEX_CACHE_STALE:
        result = true;
        break;
    case DEX_CACHE_STALE_ODEX:
        dvmThrowException("Ldalvik/system/StaleDexCacheError;", name);
        result = -1;
        break;
    }
    free(name);

    if (result >= 0) {
        RETURN_BOOLEAN(result);
    } else {
        RETURN_VOID();
    }
}
/*
 * public native boolean trackExternalAllocation(long size)
 *
 * Asks the VM if <size> bytes can be allocated in an external heap.
 * This information may be used to limit the amount of memory available
 * to Dalvik threads.  Returns false if the VM would rather that the caller
 * did not allocate that much memory.  If the call returns false, the VM
 * will not update its internal counts.
 */
static void Dalvik_dalvik_system_VMRuntime_trackExternalAllocation(
    const u4* args, JValue* pResult)
{
    s8 longSize = GET_ARG_LONG(args, 1);

    /* Fit in 32 bits. */
    if (longSize < 0) {
        dvmThrowException("Ljava/lang/IllegalArgumentException;",
            "size must be positive");
        RETURN_VOID();
    } else if (longSize > INT_MAX) {
        dvmThrowException("Ljava/lang/UnsupportedOperationException;",
            "size must fit in 32 bits");
        RETURN_VOID();
    }
    RETURN_BOOLEAN(dvmTrackExternalAllocation((size_t)longSize));
}
예제 #15
0
/*
 * boolean isInterrupted()
 *
 * Determine if the specified thread has been interrupted.  Does not clear
 * the flag.
 */
static void Dalvik_java_lang_VMThread_isInterrupted(const u4* args,
    JValue* pResult)
{
    Object* thisPtr = (Object*) args[0];
    Thread* thread;
    bool interrupted;

    dvmLockThreadList(NULL);
    thread = dvmGetThreadFromThreadObject(thisPtr);
    if (thread != NULL)
        interrupted = thread->interrupted;
    else
        interrupted = false;
    dvmUnlockThreadList();

    RETURN_BOOLEAN(interrupted);
}
예제 #16
0
/*
 * boolean holdsLock(Object object)
 *
 * Returns whether the current thread has a monitor lock on the specific
 * object.
 */
static void Dalvik_java_lang_VMThread_holdsLock(const u4* args, JValue* pResult)
{
    Object* thisPtr = (Object*) args[0];
    Object* object = (Object*) args[1];
    Thread* thread;

    if (object == NULL) {
        dvmThrowNullPointerException("object == null");
        RETURN_VOID();
    }

    dvmLockThreadList(NULL);
    thread = dvmGetThreadFromThreadObject(thisPtr);
    int result = dvmHoldsLock(thread, object);
    dvmUnlockThreadList();

    RETURN_BOOLEAN(result);
}
예제 #17
0
jbool fastiva_Dalvik_dalvik_system_VMRuntime_isDebuggerActive(dalvik_system_VMRuntime_p self) {
#endif

	RETURN_BOOLEAN(gDvm.debuggerActive || gDvm.nativeDebuggerActive);
}
static void Dalvik_dalvik_system_VMRuntime_isDebuggerActive(
    const u4* args, JValue* pResult)
{
    RETURN_BOOLEAN(gDvm.debuggerActive || gDvm.nativeDebuggerActive);
}
/*
 * static boolean cacheRegisterMap(String classAndMethodDescr)
 *
 * If the specified class is loaded, and the named method exists, ensure
 * that the method's register map is ready for use.  If the class/method
 * cannot be found, nothing happens.
 *
 * This can improve the zygote's sharing of compressed register maps.  Do
 * this after class preloading.
 *
 * Returns true if the register map is cached and ready, either as a result
 * of this call or earlier activity.  Returns false if the class isn't loaded,
 * if the method couldn't be found, or if the method has no register map.
 *
 * (Uncomment logs in dvmGetExpandedRegisterMap0() to gather stats.)
 */
static void Dalvik_dalvik_system_VMDebug_cacheRegisterMap(const u4* args,
    JValue* pResult)
{
    StringObject* classAndMethodDescStr = (StringObject*) args[0];
    ClassObject* clazz;
    bool result = false;

    if (classAndMethodDescStr == NULL) {
        dvmThrowNullPointerException("classAndMethodDesc == null");
        RETURN_VOID();
    }

    char* classAndMethodDesc = NULL;

    /*
     * Pick the string apart.  We have a local copy, so just modify it
     * in place.
     */
    classAndMethodDesc = dvmCreateCstrFromString(classAndMethodDescStr);

    char* methodName = strchr(classAndMethodDesc, '.');
    if (methodName == NULL) {
        dvmThrowRuntimeException("method name not found in string");
        RETURN_VOID();
    }
    *methodName++ = '\0';

    char* methodDescr = strchr(methodName, ':');
    if (methodDescr == NULL) {
        dvmThrowRuntimeException("method descriptor not found in string");
        RETURN_VOID();
    }
    *methodDescr++ = '\0';

    //ALOGD("GOT: %s %s %s", classAndMethodDesc, methodName, methodDescr);

    /*
     * Find the class, but only if it's already loaded.
     */
    clazz = dvmLookupClass(classAndMethodDesc, NULL, false);
    if (clazz == NULL) {
        ALOGD("Class %s not found in bootstrap loader", classAndMethodDesc);
        goto bail;
    }

    Method* method;

    /*
     * Find the method, which could be virtual or direct, defined directly
     * or inherited.
     */
    if (methodName[0] == '<') {
        /*
         * Constructor or class initializer.  Only need to examine the
         * "direct" list, and don't need to search up the class hierarchy.
         */
        method = dvmFindDirectMethodByDescriptor(clazz, methodName,
                    methodDescr);
    } else {
        /*
         * Try both lists, and scan up the tree.
         */
        method = dvmFindVirtualMethodHierByDescriptor(clazz, methodName,
                    methodDescr);
        if (method == NULL) {
            method = dvmFindDirectMethodHierByDescriptor(clazz, methodName,
                        methodDescr);
        }
    }

    if (method != NULL) {
        /*
         * Got it.  See if there's a register map here.
         */
        const RegisterMap* pMap;
        pMap = dvmGetExpandedRegisterMap(method);
        if (pMap == NULL) {
            ALOGV("No map for %s.%s %s",
                classAndMethodDesc, methodName, methodDescr);
        } else {
            ALOGV("Found map %s.%s %s",
                classAndMethodDesc, methodName, methodDescr);
            result = true;
        }
    } else {
        ALOGV("Unable to find %s.%s %s",
            classAndMethodDesc, methodName, methodDescr);
    }

bail:
    free(classAndMethodDesc);
    RETURN_BOOLEAN(result);
}
/*
 * private static native boolean VMSupportsCS8();
 */
static void Dalvik_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8(
    const u4* args, JValue* pResult)
{
    UNUSED_PARAMETER(args);
    RETURN_BOOLEAN(1);
}