在 Android 上运行生成的 ARM 机器代码会出现带有 Java Bitmap 对象的 UnsupportedOperationException

发布于 2024-12-02 01:10:51 字数 608 浏览 1 评论 0原文

我们( http://www.mosync.com )已经使用 Android NDK 编译了我们的 ARM 重新编译器,该编译器采用我们的内部字节代码并生成 ARM 机器代码。当执行重新编译的代码时,我们看到性能有了巨大的提高,除了一个小例外,我们无法使用任何 Java 位图操作。 本机系统使用一个函数来处理重新编译的代码正在调用的对 Java 端的所有调用。在 Java (Dalvik) 方面,我们绑定了 Android 功能。重新编译代码或执行机器代码时没有问题。完全相同的源代码适用于 Symbian 和 Windows Mobile 6.x,因此重新编译器似乎生成了正确的 ARM 机器代码。 就像我说的,我们遇到的问题是我们不能使用 Java Bitmap 对象。我们已经验证了从Java代码发送的参数是正确的,并且我们尝试在Android自己的JNI系统中执行下来。问题是我们得到了一个 UnsupportedOperationException ,其中包含“大小必须适合 32 位”。该问题在 Android 1.5 到 2.3 上似乎一致。我们尚未在任何 Android 3 设备上尝试过重新编译器。

这是其他人遇到过的错误吗?我猜其他开发人员也做过类似的事情。

We ( http://www.mosync.com ) have compiled our ARM recompiler with the Android NDK which takes our internal byte code and generates ARM machine code. When executing recompiled code we see an enormous increase in performance, with one small exception, we can't use any Java Bitmap operations.
The native system uses a function which takes care of all the calls to the Java side which the recompiled code is calling. On the Java (Dalvik) side we then have bindings to Android features. There are no problems while recompiling the code or when executing the machine code. The exact same source code works on Symbian and Windows Mobile 6.x so the recompiler seems to generate correct ARM machine code.
Like I said, the problem we have is that we can't use Java Bitmap objects. We have verified that the parameters which are sent from the Java code is correct, and we have tried following the execution down in Android's own JNI systems. The problem is that we get an UnsupportedOperationException with "size must fit in 32 bits.". The problem seems consistent on Android 1.5 to 2.3. We haven't tried the recompiler on any Android 3 devices.

Is this a bug which other people have encountered, I guess other developers have done similar things.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

内心激荡 2024-12-09 01:10:51

我在 dalvik_system_VMRuntime.c

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

例如,从 GraphicsJNI::setJavaPixelRef 调用此方法:

size_t size = size64.get32();
jlong jsize = size;  // the VM wants longs for the size
if (reportSizeToVM) {
    //    SkDebugf("-------------- inform VM we've allocated %d bytes\n", size);
    bool r = env->CallBooleanMethod(gVMRuntime_singleton,
                                gVMRuntime_trackExternalAllocationMethodID,
                                jsize);

我想说,您调用的代码似乎是试图分配太大的尺寸。如果您显示失败的实际 Java 调用以及传递给它的所有参数的值,可能会更容易找到原因。

I found the message in dalvik_system_VMRuntime.c:

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

This method is called, for example, from GraphicsJNI::setJavaPixelRef:

size_t size = size64.get32();
jlong jsize = size;  // the VM wants longs for the size
if (reportSizeToVM) {
    //    SkDebugf("-------------- inform VM we've allocated %d bytes\n", size);
    bool r = env->CallBooleanMethod(gVMRuntime_singleton,
                                gVMRuntime_trackExternalAllocationMethodID,
                                jsize);

I would say it seems that the code you're calling is trying to allocate a too big size. If you show the actual Java call which fails and values of all the arguments that you pass to it, it might be easier to find the reason.

旧话新听 2024-12-09 01:10:51

我设法找到了解决方法。当我将所有 Bitmap.createBitmap 调用包装在 Activity.runOnUiThread() 内时,它可以工作。

I managed to find a work-around. When I wrap all the Bitmap.createBitmap calls inside a Activity.runOnUiThread() It works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文