/* * static void startMethodTracingFd(String traceFileName, FileDescriptor fd, * int bufferSize, int flags, boolean samplingEnabled, int intervalUs) * * Start method trace profiling, sending results to a file descriptor. */ static void Dalvik_dalvik_system_VMDebug_startMethodTracingFd(const u4* args, JValue* pResult) { StringObject* traceFileStr = (StringObject*) args[0]; Object* traceFd = (Object*) args[1]; int bufferSize = args[2]; int flags = args[3]; bool samplingEnabled = args[4]; int intervalUs = args[5]; int origFd = getFileDescriptor(traceFd); if (origFd < 0) RETURN_VOID(); int fd = dup(origFd); if (fd < 0) { dvmThrowExceptionFmt(gDvm.exRuntimeException, "dup(%d) failed: %s", origFd, strerror(errno)); RETURN_VOID(); } char* traceFileName = dvmCreateCstrFromString(traceFileStr); if (traceFileName == NULL) { RETURN_VOID(); } dvmMethodTraceStart(traceFileName, fd, bufferSize, flags, false, samplingEnabled, intervalUs); free(traceFileName); RETURN_VOID(); }
static void Dalvik_dalvik_system_VMRuntime_newNonMovableArray(const u4* args, JValue* pResult) { ClassObject* elementClass = (ClassObject*) args[1]; int length = args[2]; if (elementClass == NULL) { dvmThrowNullPointerException("elementClass == null"); RETURN_VOID(); } if (length < 0) { dvmThrowNegativeArraySizeException(length); RETURN_VOID(); } // TODO: right now, we don't have a copying collector, so there's no need // to do anything special here, but we ought to pass the non-movability // through to the allocator. ClassObject* arrayClass = dvmFindArrayClassForElement(elementClass); ArrayObject* newArray = dvmAllocArrayByClass(arrayClass, length, ALLOC_NON_MOVING); if (newArray == NULL) { assert(dvmCheckException(dvmThreadSelf())); RETURN_VOID(); } dvmReleaseTrackedAlloc((Object*) newArray, NULL); RETURN_PTR(newArray); }
/* * public static native void getHeapSpaceStats(long[] data) */ static void Dalvik_dalvik_system_VMDebug_getHeapSpaceStats(const u4* args, JValue* pResult) { ArrayObject* dataArray = (ArrayObject*) args[0]; if (dataArray == NULL || dataArray->length < 6) { RETURN_VOID(); } jlong* arr = (jlong*)(void*)dataArray->contents; int j = 0; size_t per_heap_allocated[2]; size_t per_heap_size[2]; memset(per_heap_allocated, 0, sizeof(per_heap_allocated)); memset(per_heap_size, 0, sizeof(per_heap_size)); dvmHeapSourceGetValue(HS_BYTES_ALLOCATED, (size_t*) &per_heap_allocated, 2); dvmHeapSourceGetValue(HS_FOOTPRINT, (size_t*) &per_heap_size, 2); jlong heapSize = per_heap_size[0]; jlong heapUsed = per_heap_allocated[0]; jlong heapFree = heapSize - heapUsed; jlong zygoteSize = per_heap_size[1]; jlong zygoteUsed = per_heap_allocated[1]; jlong zygoteFree = zygoteSize - zygoteUsed; arr[j++] = heapSize; arr[j++] = heapUsed; arr[j++] = heapFree; arr[j++] = zygoteSize; arr[j++] = zygoteUsed; arr[j++] = zygoteFree; RETURN_VOID(); }
static void print_dlopen_error(YogEnv* env, YogHandle* filename) { SAVE_LOCALS(env); if (!env->vm->debug_import) { RETURN_VOID(env); } const char* msg; #if defined(__MINGW32__) || defined(_MSC_VER) TCHAR buf[1024]; if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, buf, array_sizeof(buf), NULL) != 0) { RETURN_VOID(env); } msg = (const char*)buf; #else msg = dlerror(); if (msg == NULL) { RETURN_VOID(env); } #endif #if defined(__linux__) fprintf(stderr, "%s\n", msg); #else YogVal bin = YogString_to_bin_in_default_encoding(env, filename); fprintf(stderr, "%s: %s\n", BINARY_CSTR(bin), msg); #endif RETURN_VOID(env); }
static void exec_get_attr(YogEnv* env, YogVal self, ID name) { SAVE_ARG(env, self); YogVal klass = YUNDEF; YogVal attr = YUNDEF; PUSH_LOCALS2(env, klass, attr); klass = YogVal_get_class(env, self); attr = YogClass_get_attr(env, klass, name); if (!IS_UNDEF(attr)) { attr = YogVal_get_descr(env, attr, self, klass); YogScriptFrame_push_stack(env, env->frame, attr); RETURN_VOID(env); } attr = YogObj_get_attr(env, self, name); if (!IS_UNDEF(attr)) { attr = YogVal_get_descr(env, attr, YNIL, self); YogScriptFrame_push_stack(env, env->frame, attr); RETURN_VOID(env); } YogError_raise_AttributeError(env, "%C object has no attribute \"%I\"", self, name); /* NOTREACHED */ RETURN_VOID(env); }
/* * static void dumpHprofData(String fileName, FileDescriptor fd) * * Cause "hprof" data to be dumped. We can throw an IOException if an * error occurs during file handling. */ static void Dalvik_dalvik_system_VMDebug_dumpHprofData(const u4* args, JValue* pResult) { #ifdef WITH_HPROF StringObject* fileNameStr = (StringObject*) args[0]; Object* fileDescriptor = (Object*) args[1]; char* fileName; int result; /* * Only one of these may be NULL. */ if (fileNameStr == NULL && fileDescriptor == NULL) { dvmThrowException("Ljava/lang/NullPointerException;", NULL); RETURN_VOID(); } if (fileNameStr != NULL) { fileName = dvmCreateCstrFromString(fileNameStr); if (fileName == NULL) { /* unexpected -- malloc failure? */ dvmThrowException("Ljava/lang/RuntimeException;", "malloc failure?"); RETURN_VOID(); } } else { fileName = strdup("[fd]"); } int fd = -1; if (fileDescriptor != NULL) { fd = getFileDescriptor(fileDescriptor); if (fd < 0) RETURN_VOID(); } result = hprofDumpHeap(fileName, fd, false); free(fileName); if (result != 0) { /* ideally we'd throw something more specific based on actual failure */ dvmThrowException("Ljava/lang/RuntimeException;", "Failure during heap dump -- check log output for details"); RETURN_VOID(); } #else dvmThrowException("Ljava/lang/UnsupportedOperationException;", NULL); #endif RETURN_VOID(); }
/* * private Object getField(Object o, Class declaringClass, Class type, * int slot, boolean noAccessCheck) * * Primitive types need to be boxed. */ static void Dalvik_java_lang_reflect_Field_getField(const u4* args, JValue* pResult) { // ignore thisPtr in args[0] Object* obj = (Object*) args[1]; ClassObject* declaringClass = (ClassObject*) args[2]; ClassObject* fieldType = (ClassObject*) args[3]; int slot = args[4]; bool noAccessCheck = (args[5] != 0); JValue value; const JValue* fieldPtr; DataObject* result; //dvmDumpClass(obj->clazz, kDumpClassFullDetail); /* get a pointer to the field's data; performs access checks */ fieldPtr = getFieldDataAddr(obj, declaringClass, slot, false,noAccessCheck); if (fieldPtr == NULL) RETURN_VOID(); /* copy 4 or 8 bytes out */ if (fieldType->primitiveType == PRIM_LONG || fieldType->primitiveType == PRIM_DOUBLE) { value.j = fieldPtr->j; } else { value.i = fieldPtr->i; } result = dvmWrapPrimitive(value, fieldType); dvmReleaseTrackedAlloc((Object*) result, NULL); RETURN_PTR(result); }
void YogRegexp_define_classes(YogEnv* env, YogVal pkg) { SAVE_ARG(env, pkg); YogVal cRegexp = YUNDEF; YogVal cMatch = YUNDEF; PUSH_LOCALS2(env, cRegexp, cMatch); YogVM* vm = env->vm; cRegexp = YogClass_new(env, "Regexp", vm->cObject); #define DEFINE_METHOD(name, ...) do { \ YogClass_define_method2(env, cRegexp, pkg, (name), __VA_ARGS__); \ } while (0) DEFINE_METHOD("match", match, "s", "|", "pos", NULL); DEFINE_METHOD("search", search, "s", "|", "pos", NULL); #undef DEFINE_METHOD vm->cRegexp = cRegexp; cMatch = YogClass_new(env, "Match", vm->cObject); #define DEFINE_METHOD(name, f) do { \ YogClass_define_method(env, cMatch, pkg, (name), (f)); \ } while (0) DEFINE_METHOD("start", start); DEFINE_METHOD("end", end); #undef DEFINE_METHOD #define DEFINE_METHOD2(name, ...) do { \ YogClass_define_method2(env, cMatch, pkg, (name), __VA_ARGS__); \ } while (0) DEFINE_METHOD2("group", group, "|", "group", NULL); #undef DEFINE_METHOD2 vm->cMatch = cMatch; RETURN_VOID(env); }
/* * public void gc() * * Initiate a gc. */ static void Dalvik_java_lang_Runtime_gc(const u4* args, JValue* pResult) { UNUSED_PARAMETER(args); dvmCollectGarbage(false); RETURN_VOID(); }
static void exec_set_descr(YogEnv* env, YogVal attr, YogVal obj, YogVal val) { SAVE_ARGS3(env, attr, obj, val); YogVal setter = YUNDEF; YogVal class_of_setter = YUNDEF; YogVal method = YUNDEF; YogVal class_of_method = YUNDEF; YogVal class_of_obj = YUNDEF; PUSH_LOCALS5(env, setter, class_of_setter, method, class_of_method, class_of_obj); YogHandle* args[] = { YogHandle_REGISTER(env, val) }; setter = PTR_AS(YogProperty, attr)->setter; class_of_setter = YogVal_get_class(env, setter); if (!IS_PTR(setter)) { ID id = PTR_AS(YogClass, class_of_setter)->name; YogError_raise_TypeError(env, "\"%I\" object is not callable", id); } class_of_obj = YogVal_get_class(env, obj); YOG_ASSERT(env, PTR_AS(YogClass, class_of_setter)->call_get_descr != NULL, "can't make instance method"); method = PTR_AS(YogClass, class_of_setter)->call_get_descr(env, setter, obj, class_of_obj); YOG_ASSERT(env, IS_PTR(method), "method isn't pointer"); class_of_method = YogVal_get_class(env, method); Executor exec = PTR_AS(YogClass, class_of_method)->exec; YOG_ASSERT(env, exec != NULL, "method isn't callable"); YogHandle* h_method = YogHandle_REGISTER(env, method); exec(env, h_method, array_sizeof(args), args, 0, NULL, NULL, NULL, NULL); RETURN_VOID(env); }
static void exec_get_descr(YogEnv* env, YogVal attr, YogVal obj, YogVal klass) { SAVE_ARGS3(env, attr, obj, klass); YogVal getter = YUNDEF; YogVal class_of_getter = YUNDEF; YogVal method = YUNDEF; YogVal class_of_method = YUNDEF; PUSH_LOCALS4(env, getter, class_of_getter, method, class_of_method); getter = PTR_AS(YogProperty, attr)->getter; class_of_getter = YogVal_get_class(env, getter); if (!IS_PTR(getter)) { ID id = PTR_AS(YogClass, class_of_getter)->name; YogError_raise_TypeError(env, "\"%I\" object is not callable", id); } YOG_ASSERT(env, PTR_AS(YogClass, class_of_getter)->call_get_descr != NULL, "can't make instance method"); method = PTR_AS(YogClass, class_of_getter)->call_get_descr(env, getter, obj, klass); YOG_ASSERT(env, IS_PTR(method), "method isn't pointer"); class_of_method = YogVal_get_class(env, method); Executor exec = PTR_AS(YogClass, class_of_method)->exec; YOG_ASSERT(env, exec != NULL, "method isn't callable"); YogHandle* h_method = YogHandle_REGISTER(env, method); exec(env, h_method, 0, NULL, 0, NULL, NULL, NULL, NULL); RETURN_VOID(env); }
CompetitorInfo(ROLE* role) { memset(this, 0, sizeof(*this)); RETURN_VOID(role == NULL); memcpy(this->szName, role->roleName.c_str(), sizeof(this->szName)-1); this->dwID = role->dwRoleID; this->bySex = role->bySex; this->byJob = role->byJob; this->dwFightValue = role->dwFightValue; this->wLevel = role->wLevel; auto it = ARENA::mapRoleIDRank.find( role->dwRoleID ); if ( it != ARENA::mapRoleIDRank.end() ) { this->dwRank = it->second; } CONFIG::ARENA_BOUNS_CFG *arenaBounsCfg = CONFIG::getArenaBounsCfg(this->dwRank); if( arenaBounsCfg != NULL) { this->dwMoney = arenaBounsCfg->goldNum; this->wChipID = arenaBounsCfg->itemID; this->wChipNum = arenaBounsCfg->itemNum; } }
static void raise_ZipError(YogEnv* env, YogVal pkg, const char* msg) { SAVE_ARG(env, pkg); YogVal eZipError = YUNDEF; YogVal e = YUNDEF; YogVal s = YUNDEF; PUSH_LOCALS3(env, eZipError, e, s); if (!IS_PTR(pkg) || (BASIC_OBJ_TYPE(pkg) != TYPE_ZIP_PKG)) { YogError_raise_TypeError(env, "package type must be TYPE_ZIP_PKG"); } eZipError = PTR_AS(Package, pkg)->eZipError; if (msg != NULL) { s = YogString_from_string(env, msg); e = YogEval_call_method1(env, eZipError, "new", s); } else { e = YogEval_call_method0(env, eZipError, "new"); } YogError_raise(env, e); /* NOTREACHED */ RETURN_VOID(env); }
/* * public native void gcSoftReferences() * * Does a GC and forces collection of SoftReferences that are * not strongly-reachable. */ static void Dalvik_dalvik_system_VMRuntime_gcSoftReferences(const u4* args, JValue* pResult) { dvmCollectGarbage(true); RETURN_VOID(); }
void YogClass_class_init(YogEnv* env, YogVal cClass, YogVal pkg) { SAVE_ARGS2(env, cClass, pkg); YogClass_define_method(env, cClass, pkg, "new", new_); RETURN_VOID(env); }
/* * native float nativeSetTargetHeapUtilization() * * Sets the current ideal heap utilization, represented as a number * between zero and one. Returns the old utilization. * * Note that this is NOT static. */ static void Dalvik_dalvik_system_VMRuntime_nativeSetTargetHeapUtilization( const u4* args, JValue* pResult) { dvmSetTargetHeapUtilization(dvmU4ToFloat(args[1])); RETURN_VOID(); }
/* * public native void runFinalizationSync() * * Does not return until any pending finalizers have been called. * This may or may not happen in the context of the calling thread. * No exceptions will escape. * * Used by zygote, which doesn't have a HeapWorker thread. */ static void Dalvik_dalvik_system_VMRuntime_runFinalizationSync(const u4* args, JValue* pResult) { dvmRunFinalizationSync(); RETURN_VOID(); }
/* * static void dumpHprofDataDdms() * * Cause "hprof" data to be computed and sent directly to DDMS. */ static void Dalvik_dalvik_system_VMDebug_dumpHprofDataDdms(const u4* args, JValue* pResult) { int result; result = hprofDumpHeap("[DDMS]", -1, true); if (result != 0) { /* ideally we'd throw something more specific based on actual failure */ dvmThrowRuntimeException( "Failure during heap dump; check log output for details"); RETURN_VOID(); } RETURN_VOID(); }
void fastiva_Dalvik_dalvik_system_VMRuntime_nativeSetTargetHeapUtilization(dalvik_system_VMRuntime_p self, jfloat v) { #endif dvmSetTargetHeapUtilization(v); RETURN_VOID(); }
/* * static boolean resetInstructionCount() * * Reset the instruction count array. */ static void Dalvik_dalvik_system_VMDebug_resetInstructionCount(const u4* args, JValue* pResult) { sched_yield(); memset(gDvm.executedInstrCounts, 0, kNumPackedOpcodes * sizeof(int)); RETURN_VOID(); }
/* * 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(); } }
/* * private void setField(Object o, Class declaringClass, Class type, * int slot, boolean noAccessCheck, Object value) * * When assigning into a primitive field we will automatically extract * the value from box types. */ static void Dalvik_java_lang_reflect_Field_setField(const u4* args, JValue* pResult) { // ignore thisPtr in args[0] Object* obj = (Object*) args[1]; ClassObject* declaringClass = (ClassObject*) args[2]; ClassObject* fieldType = (ClassObject*) args[3]; int slot = args[4]; bool noAccessCheck = (args[5] != 0); Object* valueObj = (Object*) args[6]; JValue* fieldPtr; JValue value; /* unwrap primitive, or verify object type */ if (!dvmUnwrapPrimitive(valueObj, fieldType, &value)) { dvmThrowException("Ljava/lang/IllegalArgumentException;", "invalid value for field"); RETURN_VOID(); } /* get a pointer to the field's data; performs access checks */ fieldPtr = getFieldDataAddr(obj, declaringClass, slot, true, noAccessCheck); if (fieldPtr == NULL) RETURN_VOID(); /* store 4 or 8 bytes */ if (fieldType->primitiveType == PRIM_LONG || fieldType->primitiveType == PRIM_DOUBLE) { fieldPtr->j = value.j; } else if (fieldType->primitiveType == PRIM_NOT) { if (slot < 0) { StaticField *sfield; sfield = (StaticField *)dvmSlotToField(declaringClass, slot); assert(fieldPtr == &sfield->value); dvmSetStaticFieldObject(sfield, value.l); } else { int offset = declaringClass->ifields[slot].byteOffset; assert(fieldPtr == (JValue *)BYTE_OFFSET(obj, offset)); dvmSetFieldObject(obj, offset, value.l); } } else { fieldPtr->i = value.i; } RETURN_VOID(); }
/* * public static void stopAllocCounting() */ static void Dalvik_dalvik_system_VMDebug_stopAllocCounting(const u4* args, JValue* pResult) { UNUSED_PARAMETER(args); dvmStopAllocCounting(); 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)); }
/* * public void wait(long ms, int ns) throws InterruptedException */ static void Dalvik_java_lang_Object_wait(const u4* args, JValue* pResult, const Method* method, Thread* self) { Object* thisPtr = (Object*) args[0]; dvmObjectWait(self, thisPtr, GET_ARG_LONG(args,1), (s4)args[3], true); RETURN_VOID(); }
/* * public void notifyAll() */ static void Dalvik_java_lang_Object_notifyAll(const u4* args, JValue* pResult, const Method* method, Thread* self) { Object* thisPtr = (Object*) args[0]; dvmObjectNotifyAll(self, thisPtr); RETURN_VOID(); }
static void raise_invalid_group(YogEnv* env, YogVal group) { SAVE_ARG(env, group); YogError_raise_TypeError(env, "group must be a Fixnum, String or nil, not %C", group); /* NOTREACHED */ RETURN_VOID(env); }
/* * static void stopEmulatorTracing() * * Start sending method trace info to the emulator. */ static void Dalvik_dalvik_system_VMDebug_stopEmulatorTracing(const u4* args, JValue* pResult) { UNUSED_PARAMETER(args); dvmEmulatorTraceStop(); RETURN_VOID(); }
/* * public static void resetAllocCount(int kinds) */ static void Dalvik_dalvik_system_VMDebug_resetAllocCount(const u4* args, JValue* pResult) { unsigned int kinds = args[0]; clearAllocProfStateFields(&gDvm.allocProf, kinds & 0xffff); clearAllocProfStateFields(&dvmThreadSelf()->allocProf, kinds >> 16); RETURN_VOID(); }
/* * Primitive field setters, e.g.: * private void setIField(Object o, Class declaringClass, * Class type, int slot, boolean noAccessCheck, int type_no, int value) * * The "type_no" is defined by the java.lang.reflect.Field class. */ static void Dalvik_java_lang_reflect_Field_setPrimitiveField(const u4* args, JValue* pResult) { // ignore thisPtr in args[0] Object* obj = (Object*) args[1]; ClassObject* declaringClass = (ClassObject*) args[2]; ClassObject* fieldType = (ClassObject*) args[3]; int slot = args[4]; bool noAccessCheck = (args[5] != 0); int typeNum = args[6]; const s4* valuePtr = (s4*) &args[7]; PrimitiveType srcType = convPrimType(typeNum); JValue* fieldPtr; JValue value; if (!dvmIsPrimitiveClass(fieldType)) { dvmThrowException("Ljava/lang/IllegalArgumentException;", "not a primitive field"); RETURN_VOID(); } /* convert the 32/64-bit arg to a JValue matching the field type */ if (dvmConvertPrimitiveValue(srcType, fieldType->primitiveType, valuePtr, &(value.i)) < 0) { dvmThrowException("Ljava/lang/IllegalArgumentException;", "invalid primitive conversion"); RETURN_VOID(); } /* get a pointer to the field's data; performs access checks */ fieldPtr = getFieldDataAddr(obj, declaringClass, slot, true, noAccessCheck); if (fieldPtr == NULL) RETURN_VOID(); /* store 4 or 8 bytes */ if (fieldType->primitiveType == PRIM_LONG || fieldType->primitiveType == PRIM_DOUBLE) { fieldPtr->j = value.j; } else { fieldPtr->i = value.i; } RETURN_VOID(); }