Подтвердить что ты не робот

JamVM для Motorola FX9500 Проблемы - что мне делать?

Я использую Motorola FX9500 RFID-считыватель, который запускает Linux с jamvm версии 1.5.0 (я могу только развернуть приложения к нему - я не могу изменить виртуальную машину Java или что-то еще, так что мои параметры ограничены) - вот что я вижу, когда проверяю версию:

[[email protected] ~]$ /usr/bin/jamvm -version
java version "1.5.0"
JamVM version 1.5.4
Copyright (C) 2003-2010 Robert Lougher <[email protected]>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2,
or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

Build information:

Execution Engine: inline-threaded interpreter with stack-caching
Compiled with: gcc 4.2.2

Boot Library Path: /usr/lib/classpath
Boot Class Path: /usr/local/jamvm/share/jamvm/classes.zip:/usr/share/classpath/glibj.zip

Мне нужно написать приложение, чтобы я схватил Oracle Java SDK 1.5.0 и установил его на свой ПК с Windows 7, поэтому у него есть эта версия:

C:\>javac -version
javac 1.5.0

Я слишком идеалистичен в отношении того, что приложение, которое я компилирую с этим компилятором, будет корректно работать над вышеупомянутым JamVM? Во всяком случае, нажимая на невежество, я пишу это небольшое приложение:

public final class TestApp {
    public static void main(final String[] args) {
        long p = Long.MIN_VALUE;
        int o = (int)(-(p + 10) % 10);
        System.out.println(o);
    }
}

Скомпилируйте его с вышеупомянутым компилятором javac и запустите его на ПК следующим образом:

C:\>javac TestApp.java

C:\>java TestApp
8

Все отлично. Жизнь хорошая, поэтому я беру этот файл .class и помещаю его на FX9500 и запускаю его так:

[[email protected] ~]$ /usr/bin/jamvm TestApp
-2

Eek, что... как вы можете видеть - он возвращает другой результат.

Итак, почему и кто не прав или это что-то вроде спецификации, неясно, как справляться с этим расчетом (конечно же, нет)? Может быть, мне нужно скомпилировать его с помощью другого компилятора?


Почему я об этом забочусь?

Причина, по которой я пришел к этой ситуации, заключается в том, что расчет точно так же происходит внутри java.lang.Long.toString, и у меня есть ошибка в моем реальном приложении, где я выхожу из long и получаю a java.lang.ArrayIndexOutOfBoundsException. Поскольку значение, которое я хочу регистрировать, вполне может быть на концах Long.

Я думаю, что могу обойти это, проверив Long.MIN_VALUE и Long.MAX_VALUE и запустив в журнал "Err, я не могу сказать вам номер, но на самом деле это Long.XXX, поверьте, я вам солгал?". Но когда я нахожу это, я чувствую, что мое приложение теперь построено на песчаном фундаменте, и оно должно быть действительно надежным. Я серьезно подумываю просто сказать, что JamVM не справляется с заданием и записывает приложение в Python (поскольку у читателя также есть время выполнения Python).

Я как бы надеюсь, что кто-то скажет мне, что я сумасшедший, и я должен был скомпилировать его на моем ПК с Windows, например... и тогда это сработает, поэтому, пожалуйста, скажите мне, что (если это правда, конечно)!


Обновление

Noofiz заставил меня думать (спасибо), и я сбил это дополнительное тестовое приложение:

public final class TestApp2 {
    public static void main(final String[] args) {

        long p = Long.MIN_VALUE + 10;

        if (p != -9223372036854775798L) {
            System.out.println("O....M.....G");
            return;
        }

        p = -p;

        if (p != 9223372036854775798L) {
            System.out.println("W....T.....F");
            return;            
        }

        int o = (int)(p % 10);

        if (o != 8) {
            System.out.println("EEEEEK");
            return;
        }

        System.out.println("Phew, that was a close one");
    }
}

Я снова собираюсь на машине Windows и запускаю ее.

Он печатает Phew, that was a close one

Я копирую файл .class в интересующее устройство и запускаю его.

Он печатает...

... дождитесь его...

W....T.....F

Боже мой. Я чувствую себя немного одурманенным, думаю, мне нужна чашка чая...

Обновление 2

Еще одна вещь, которую я пробовал, которая не имела никакого значения, заключалась в том, чтобы скопировать файлы classes.zip и glibj.zip с FX9500 на ПК, а затем сделать кросс-компиляцию так (это должен означать скомпилированный файл должно быть в порядке?):

javac -source 1.4 -target 1.4 -bootclasspath classes.zip;glibj.zip -extdirs "" TestApp2.java

Но полученный файл .class, когда он запускается на считывателе, печатает одно и то же сообщение.

4b9b3361

Ответ 1

Я написал JamVM. Как вы, вероятно, догадались бы, такие ошибки были бы замечены к настоящему времени, и JamVM не пропустил бы с ними даже самых простых наборов тестов (у GNU Classpath есть свой собственный Mauve, а OpenJDK - jtreg). Я регулярно запускаю ARM (FX9500 использует PXA270 ARM) и x86-64, но различные платформы проходят тестирование как часть IcedTea.

Поэтому я не очень понимаю, что здесь произошло. Я предполагаю, что это влияет только на Java longs, поскольку они используются нечасто, и поэтому большинство программ работают. JamVM отображает Java longs на длинные длинные C, поэтому я предполагаю, что компилятор, используемый для сборки JamVM, создает неверный код для длительной обработки 32-разрядной ARM.

К сожалению, вы не можете много сделать (кроме избегания длин), если вы не можете заменить JVM. Единственное, что вы можете сделать, это попытаться отключить JIT (простое копирование кода JIT, а также встроенная потоковая передача). Для этого используйте -Xnoinlining в командной строке, например:

jamvm -Xnoinlining...

Ответ 2

Проблема заключается в различных реализациях модуля:

public static long mod(long a, long b){
    long result = a % b;
    if (result < 0)
    {
        result += b;
    }
    return result;
}

этот код возвращает -2, а это:

public static long mod2(long a, long b){
    long result = a % b;
    if (result > 0 && a < 0)
    {
        result -= b;
    }
    return result;
}

возвращает 8. Причины, по которым JamVM делает это, за моим пониманием.

Из JLS:

15.17.3. Оператор остатка%

Операция остатка для операндов, которые являются целыми числами после двоичного кода числовое продвижение (§5.6.2) дает такое значение результата, что (a/b) * b + (a% b) равна a.

В соответствии с этим JamVM прерывает спецификацию языка. Очень плохо.

Ответ 3

Я бы прокомментировал, но по какой-то причине это требует репутации.

Длительное отрицание на этом устройстве не работает. Я не понимаю его точный характер, но если вы делаете два унарных минуса, вы возвращаетесь туда, где вы начали, например. х = 10; -x == 4294967286; -x == 10. 4294967286 очень близко к Integer.MAX_VALUE * 2 (2147483647 * 2 = 4294967294). Это еще ближе к Integer.MAX_VALUE * 2-10!

Кажется, что он изолирован от этой одной операции и не влияет на долготы более фундаментальным образом. Это просто, чтобы избежать операции в вашем собственном коде, и с помощью какого-либо некорректного использования bootclasspath можно избежать вызовов в коде класса GNU Classpath, заменив их на * -1s. Если вам нужно запустить приложение из графического интерфейса устройства, вы можете включить параметр -Xbootclasspath =... в параметр args для его передачи в JamVM).

Ошибка на самом деле уже исправлена ​​в последнем (чем последняя версия) JamVM-код: * https://github.com/ansoncat/jamvm/commit/736c2cb76baf1fedddc1eda5825908f5a0511373 * https://github.com/ansoncat/jamvm/commit/ac83bdc886ac4f6e60d684de1b4d0a5e90f1c489

но не помогает нам с фиксированной версией на устройстве. Роб Лоугер упомянул об этой проблеме как о причине выпуска новой версии JamVM, хотя я не знаю, когда это будет, или же Motorola будет достаточно убеждена в обновлении своей прошивки.

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

В любом случае у нас очень большое приложение, работающее на FX9500, и операция с длинным отрицанием не оказалась непроходимым барьером.

Удачи, Дэн.