/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * 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)); }
/* * 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); }
/* * 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); }
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); }