Методы генерации кода JIT

Проблема заключается в том, что у Firebase есть ошибка, которая после проверки подлинности вам нужно подождать, пока пользователь не появится в FirebaseAuth, а затем вы сможете ее использовать.

Что я сделал, как

Observable.fromCallable(() -> signInImpl())
        .map(this::toFirebaseUser)
        .map(this::waitForUserToAppearInAuthenticator)
        .flatMap(this::doSomethingInDatabase);

, где

@NonNull
private FirebaseUser waitForUserToAppearInAuthenticator(@NonNull final FirebaseUser user) {
    final CountDownLatch cdl = new CountDownLatch(1);
    final FirebaseAuth.AuthStateListener l = firebaseAuth -> {
        final FirebaseUser cu = firebaseAuth.getCurrentUser();
        if (cu != null && user.getUid().equals(cu.getUid())) {
            cdl.countDown();
        }
    };
    mFirebaseAuth.addAuthStateListener(l);
    try {
        cdl.await(20, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    } finally {
        mFirebaseAuth.removeAuthStateListener(l);
    }

    return user;
}
19
задан vainolo 22 May 2012 в 08:36
поделиться

7 ответов

Можно просто сделать счетчик команд точка к коду, который Вы хотите выполнить. Помните, что данные могут быть данными или кодом. На x86 счетчик команд является регистром EIP. Часть IP EIP обозначает указатель команд. Инструкцию JMP называют для перехода к адресу. После перехода EIP будет содержать этот адрес.

это что-то как hacky как отображение мнемонических инструкций к двоичным кодам, наполнение его в символ* указатель и кастинг его как функция и выполнение?

Да. Это - один способ сделать его. Получающийся код был бы брошен к указатель на функцию в C.

8
ответ дан 30 November 2019 в 04:40
поделиться

это что-то как hacky как отображение мнемонических инструкций к двоичным кодам, наполнение его в символ* указатель и кастинг его как функция и выполнение?

Да, если бы Вы делали его в C или C++ (или что-то подобное), это точно, что Вы сделали бы.

Это появляется hacky, но это - на самом деле артефакт дизайна языка. Помните, фактический алгоритм, который Вы хотите использовать, очень прост: определите, какие инструкции Вы хотите использовать, загрузить их в буфер в памяти и переход к началу того буфера.

, Если Вы действительно пытаетесь сделать, это, тем не менее, удостоверяется, что Вы разбираетесь в соглашении о вызовах, когда Вы возвращаетесь к своей программе C. Я думаю, хотел ли я сгенерировать код, я искал бы библиотеку для заботы о том аспекте для меня. Наномонета в пять центов недавно была в новостях; Вы могли посмотреть на это.

6
ответ дан 30 November 2019 в 04:40
поделиться

Да. Вы просто создаете символ* и выполняете его. Однако необходимо отметить пару деталей. Символ* должен быть в исполняемом разделе памяти и должен иметь надлежащее выравнивание.

В дополнение к наномонете в пять центов можно также проверить LLVM, который является другой библиотекой, это способно к компиляции различных представлений программы вниз указателю функции. Это - интерфейс, является чистым, и сгенерированный код имеет тенденцию быть эффективным.

4
ответ дан 30 November 2019 в 04:40
поделиться

Насколько я знаю, что это компилирует все в памяти, потому что это должно выполнить некоторую эвристику к оптимизировать код (т.е.: встраивание со временем), но можно взглянуть на Общая Исходная Общеязыковая инфраструктура 2.0 выпуск ротора. Целая кодовая база идентична.NET за исключением Дрожания и GC.

1
ответ дан 30 November 2019 в 04:40
поделиться

А также Ротор 2.0 - Вы могли также смотреть на виртуальная машина HotSpot в OpenJDK.

1
ответ дан 30 November 2019 в 04:40
поделиться

О генерации DLL: дополнительный необходимый ввод-вывод для этого, плюс соединение, плюс сложность генерации формата DLL, заставил бы так намного больше усложнить, и прежде всего они уничтожили бы производительность; дополнительно, в конце Вы все еще называете указатель функции к загруженному коду, таким образом... Кроме того, JIT-компиляция может произойти один метод за один раз, и если бы Вы хотите сделать это, Вы генерировали бы много маленьких DLLs.

Об "исполняемом разделе" требование, звоня mprotect () в системах POSIX может исправить полномочия (существует подобный API на Win32). Необходимо сделать это для большого сегмента памяти вместо этого, что однажды на метод, так как это было бы слишком медленно иначе.

На плоскости x86 Вы не заметили бы проблемы на x86 с PAE или машинами AMD64/Intel 64 битов на 64 бита, Вы получите segfault.

1
ответ дан 30 November 2019 в 04:40
поделиться

Это что-то такое же хакерское, как отображение? мнемонические инструкции для двоичного коды, вставив их в char * указатель и приведение его как функции и выполнение?

Да, это работает.

Для этого в Windows необходимо установить PAGE_EXECUTE_READWRITE на выделенный блок:

void (*MyFunc)() = (void (*)()) VirtualAlloc(NULL, sizeofblock,  MEM_COMMIT, PAGE_EXECUTE_READWRITE);

//Now fill up the block with executable code and issue-

MyFunc();
1
ответ дан 30 November 2019 в 04:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: