Запуск сгенерированного машинного кода ARM на Android дает исключение UnsupportedOperationException с растровыми объектами Java

1

Мы (http://www.mosync.com) скомпилировали наш рекомпилятор ARM с Android NDK, который берет наш внутренний байтовый код и генерирует машинный код ARM. При выполнении перекомпилированного кода мы видим огромное увеличение производительности, с одним небольшим исключением, мы не можем использовать какие-либо операции с битовой картой Java. Собственная система использует функцию, которая берет на себя все вызовы на стороне Java, которые вызывает перекомпилированный код. На стороне Java (Dalvik) у нас есть привязки к функциям Android. При перекомпиляции кода или при выполнении машинного кода проблем нет. Точный же исходный код работает на Symbian и Windows Mobile 6.x, поэтому рекомпилятор, похоже, создает правильный машинный код ARM. Как я уже сказал, проблема заключается в том, что мы не можем использовать объекты Java Bitmap. Мы проверили, что параметры, которые отправляются из Java-кода, являются правильными, и мы попытались выполнить выполнение в собственных JNI-системах Android. Проблема в том, что мы получаем UnsupportedOperationException с "размер должен соответствовать 32 бит". Проблема кажется последовательной на Android 1.5 до 2.3. Мы не пробовали рекомпилятор на любых устройствах Android 3.

Является ли это ошибкой, с которой столкнулись другие люди, я думаю, что другие разработчики сделали аналогичные вещи.

Теги:
android-ndk
arm
jni
program-transformation

2 ответа

0
Лучший ответ

Мне удалось найти работу. Когда я завершаю все вызовы Bitmap.createBitmap внутри Activity.runOnUiThread(), он работает.

0

Я нашел сообщение в 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-вызов, который терпит неудачу, и значения всех аргументов, которые вы передаете ему, может быть проще найти причину.

  • 0
    Спасибо Игорь! Даже если я сделаю Bitmap.createBitmap( 10, 10, Bitmap.Config.ARGB_8888); Я получу эту проблему. Если я вызываю createBitmap непосредственно в Java, это не проблема, но когда я вызываю то же самое из сгенерированного машинного кода ARM, эта проблема всегда возникает. Все остальные операции в порядке, мы можем инициировать сетевой вызов, Bluetooth, воспроизводить звуки и использовать new для выделения памяти внутри Java. Из всех вещей, которые мы пробовали, это только объект Bitmap, который ломается. Простейший пример, который я пробовал, использовал менее 2 МБ памяти, поэтому при создании небольших растровых изображений не должно быть проблем с памятью.
  • 0
    Как вы называете это из кода ARM? Используете функцию CallXXX от JNI? Можете ли вы показать код сборки, сгенерированный для этого вызова? Я подозреваю, что что-то может происходить с целыми числами со знаком / без знака.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню