LINUX.ORG.RU

Из простых только Lua и JavaScript. Все со статической - не простые. Чем Go не устроил? Язык быстро компилируемый, статический, и JIT даже не нужен. JIT жрёт память и CPU, хороший jit всегда сложный, лучший jit на сегодня у движка V8, но он, например, запрещён на айфонах, там свой JavaScript движок.

menangen ★★★★★
()
Ответ на: комментарий от guixoid

Молодчик!

А я вот только вид делаю, что начитанный и умный ... /но себя то не обманешь/

Владимир

anonymous
()
Ответ на: комментарий от anonymous

Добавочка.

К wiki правда нужно относиться «осторожно», а то там «научат».
К примеру суждения о иерархических базах данных
вызывает только одно чувство - «Зачем автор пишет о том, о чем слышал „на другом конце села“».

Владимир.

anonymous
()
Ответ на: комментарий от menangen

Меня интересует реализация линкования модулей/функций и hot code reloading (не знаю как правильно перевести на русский). А те же Lua и JS довольно громоздкие в этом плане проекты и просто так их исходники не прочесть

guixoid
() автор топика
Ответ на: комментарий от guixoid

Где-то на просторах инета был загрузочный образ, где первым делом запускался tcc, собирал исходники Linux и сразу же запускал собранное. Бессмысленно, но довольно эпично.

i-rinat ★★★★★
()
Ответ на: комментарий от guixoid

Lua и JS

Ты хоть пробовал? Луа очень просто написана. Жс это вообще от реализации зависит. Есть очень простые.

anonymous
()
Ответ на: комментарий от i-rinat

Tcc разве jit? Оно же вроде целиком компилит, а уже потом просто собранное пускать может. То есть это как бы не совсем то. Или я что не понимаю?

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от guixoid

Lua мелкая как блоха ты чё. Это js хрен пойми что 100500 реализаций.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от i-rinat

А я думал из AST ассемблится минимальный блок готовый к исполнению и исполняется, потом следующий блок и так далее тоесть как бы потоковое исполнение.

Тоесть если я напишу gcc main.c;./a.out это типа колхозный jit?

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

ассемблится минимальный блок готовый к исполнению и исполняется, потом следующий блок и так далее

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

ТС просит статической типизации. В Си такая есть. И он достаточно ограничен, чтобы его можно было просто целиком один раз собрать.

Тоесть если я напишу gcc main.c;./a.out это типа колхозный jit?

Недавний jit-компилятор для ruby так и делает. Я тоже обычно не это представляю, когда говорят «jit». Но, по всей видимости, это считается JIT.

i-rinat ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

А ты думал jit каждыйй раз каждую инструкцию заново компиляет, а не кэширует?

anonymous
()
Ответ на: комментарий от guixoid

hot code reloading (не знаю как правильно перевести на русский)

горячий коды перезарядка, че тупишь

anonymous
()

Ты о чем? Для любого ЯП можно сделать JIT-компиляцию. Это не от языка зависит.

anonymous
()

Java простой язык, вообще-то

yoghurt ★★★★★
()
Ответ на: комментарий от i-rinat

Когда код полностью компилируется перед запуском, называется Ahead of time compilation (AOT)

https://en.wikipedia.org/wiki/Ahead-of-time_compilation

Такое раньше использовалось в андроидах: приложение при установке, до первого запуска, компилировалось в нативный код, практически без оптимизаций. Затем, во время работы приложения, подключался еще и jit и, на основе статистики, перекомпилировал горячие куски кода с повышенными оптимизациями.

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

Из плюсов AOT - моментальный запуск приложения. На телефонах это важно. На серверах — не очень.

anonymous
()

Интересуют простые языки

Hack

Правда это почти что Java, C# и т.п. Что такое «простой язык»?

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 2)
Ответ на: комментарий от guixoid

Что ты подразумеваешь под hot code reloading? Eval’ы в языке? Возможность поменять в рантайме метод у класса/объекта?

anonymous
()
Ответ на: комментарий от guixoid

А те же Lua и JS довольно громоздкие в этом плане проекты и просто так их исходники не прочесть

Стоит ли читать исходники интерпритаторов вопрос философский.

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

Серьезные решения намного более сложные. Их так просто не осилишь. Если интересуешься темой, то стоит смотреть блоги разработчиков, документацию, выборочные куски кода. Читать теорию. Конкретные реализации, без теории, не принесут много толку.

anonymous
()
Ответ на: комментарий от anonymous

В PUC-Rio Lua ведь нет JIT, а luajit славится тем, что только полумифический Mike Paul точно знает, как оно работает.

Ceiling_QB ★★★★
()
Ответ на: комментарий от anonymous

Ну как бы да, но как бы нет. Компиляция происходит уже после запуска tcc «скрипта», и результат не сохраняется на диск для последующих запусков. Он живёт только в памяти, пока программа работает.

i-rinat ★★★★★
()

со статической типизацией

Ну можно взять какой-нибудь PureScript, его в жс - а там жит.

BRATISLAVA
()

Интересуют простые языки (не Java,C# и прочее).

VB.Net подойдёт? А если серьёзно, то любой, компилируемый в JVM или JavaScript.

hateyoufeel ★★★★★
()
Ответ на: комментарий от menangen

Чем Go не устроил? Язык быстро компилируемый, статический, и JIT даже не нужен.

lol no generics

hateyoufeel ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Перезагрузка кода на горячую

На горячую, ага. И сразу же - результат на лицо.

anonymous
()

Немного не так выразился с простыми языками. Под простым языком понимаю простой рантайм/VM, та же JVM довольно большая,а CLR так вообще гигантский.

@no-such-file

HHVM вроде довольно комплексная штуковина,но спасибо,гляну.

@LINUX-ORG-RU @i-rinat

Я не знаю на сколько верно называть gcc file.c; a.out JIT,для меня JIT компиляция это когда код функции генерируется во время исполнения и сразу может исполнятся.

Вот пример JIT’a,код генерируется во время исполнения,аллоцируется память для функции и ее сразу вызывают:


int main(int argc, char *argv[]) {
  // Machine code for:
  //   mov eax, 0
  //   ret
  unsigned char code[] = {0xb8, 0x00, 0x00, 0x00, 0x00, 0xc3};

  if (argc < 2) {
    fprintf(stderr, "Usage: jit1 <integer>\n");
    return 1;
  }

  // Overwrite immediate value "0" in the instruction
  // with the user's value.  This will make our code:
  //   mov eax, <user's value>
  //   ret
  int num = atoi(argv[1]);
  memcpy(&code[1], &num, 4);

  // Allocate writable/executable memory.
  // Note: real programs should not map memory both writable
  // and executable because it is a security risk.
  void *mem = mmap(NULL, sizeof(code), PROT_WRITE | PROT_EXEC,
                   MAP_ANON | MAP_PRIVATE, -1, 0);
  memcpy(mem, code, sizeof(code));

  // The function will return the user's value.
  int (*func)() = mem;
  return func();
}
guixoid
() автор топика
Ответ на: комментарий от guixoid

Тут у тебя код уже сгенерированный лежит, ты его просто через одно место вызываешь.

anonymous
()
Ответ на: комментарий от guixoid

для меня JIT компиляция это когда код функции генерируется во время исполнения и сразу может исполнятся.

А если ты, скажем, в программе на ходу позовёшь gcc для файла, который на ходу сгенерируешь, потом загрузишь получившуюся so-шку и вызовешь её функцию, это будет JIT?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Это я думаю можно назвать JIT'ом,есть даже библиотеки помогающие редактировать dylib файлы,но на счет редактирования кода функций не знаю

guixoid
() автор топика
Ответ на: комментарий от guixoid
// tabulate.c
#define _GNU_SOURCE
#include <assert.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>

int
main(int argc, char *argv[])
{
    if (argc < 2) {
        printf("argc < 2\n");
        return 2;
    }

    int pipe1[2];
    int pipe2[2];

    pipe(pipe1);
    pipe(pipe2);

    int c_in = pipe1[1];
    int c_out = pipe2[0];

    if (fork() == 0) {
        close(pipe1[1]);
        close(pipe2[0]);

        dup2(pipe1[0], 0);
        dup2(pipe2[1], 1);

        execlp("gcc", "gcc", "-shared", "-fPIC", "-x", "c", "-", "-lm", "-o",
               "-", NULL);
        return 1;
    }

    close(pipe1[0]);
    close(pipe2[1]);

    FILE *c_inp = fdopen(c_in, "w");
    fprintf(c_inp, "#include <math.h>\n");
    fprintf(c_inp, "double func(double x) {\n");
    fprintf(c_inp, "  return %s;\n", argv[1]);
    fprintf(c_inp, "}\n");
    fclose(c_inp);

    int code_fd = memfd_create("code", 0);
    assert(code_fd);
    FILE *c_outp = fdopen(c_out, "r");
    assert(c_outp);
    while (!feof(c_outp)) {
        char buf[4096];
        size_t read_bytes = fread(buf, 1, sizeof(buf), c_outp);
        write(code_fd, buf, read_bytes);
    }
    fclose(c_outp);

    char code_fd_name[64];
    snprintf(code_fd_name, sizeof(code_fd_name), "/proc/self/fd/%d", code_fd);

    void *handle = dlopen(code_fd_name, RTLD_NOW);
    assert(handle);
    close(code_fd);

    double (*func)(double);
    func = dlsym(handle, "func");
    assert(func);

    printf("tabulate %s:\n", argv[1]);
    for (double x = 0; x <= 1.0; x += 0.125) {
        printf("%5.3f  %f\n", x, func(x));
    }

    dlclose(handle);
    return 0;
}

Собирать так:

gcc tabulate.c -ldl -o tabulate

Использовать примерно так:

$ ./tabulate "sin(x) + cos(x) * cos(x)"
tabulate sin(x) + cos(x) * cos(x):
0.000  1.000000
0.125  1.109131
0.250  1.186195
0.375  1.232117
0.500  1.249577
0.625  1.242758
0.750  1.217007
0.875  1.178420
1.000  1.133398

Я надеюсь, понятно, что делает программа, и как именно она это делает. (И почему так делать не стоит.)

Это считается за JIT или нет? :-D Лишних файлов в файловой системе не создаётся.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Ахаха, ахаха… нет.

Я вот не называл бы JIT-(пере)компиляцией сценарии, в которых (пере)компиляция не является альтернативой другом доступном в том же рантайме способу исполнения. Но мир со мной не согласен, и называет JIT-компиляцией вообще любую компиляцию во время исполнения, а, значит, и твой пример тоже.

Я придумал, как долить наркомании в твой пример. Скорми арифметическое выражение компилятору, но не выполняй код, а выдерни ответ в виде константы из какого-нибудь LLVM IR, который он выплюнет. И пусть следующий за мной думает, как это назвать, а кто придумает, повышает градус неадекватства.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

Как-то так:

#!/usr/bin/xonsh

import re

def eval_int_c(expr):
    code = f'int main() { return {expr}; }'
    ir = $(echo @(code) | clang -O2 -S -emit-llvm -x c - -o-)
    return re.findall(r'ret i32 (.*)', ir)[0]

print(eval_int_c(input()))

Кто классифицирует это?

t184256 ★★★★★
()
Ответ на: комментарий от t184256

не является альтернативой другом доступном в том же рантайме способу исполнения

Писать интерпретатор выражений мне лениво. Но в этом нереального нет. Будет опция командной строки, управляющая вариантом подсчёта, либо интерпретация, либо предварительная компиляция и вызов функции.

Я вот не называл бы JIT-(пере)компиляцией сценарии

В ядре можно выключить eBPF интерпретатор, и оставить только eBPF JIT-компилятор. То есть любая программа, загружаемая в ядро сначала преобразуется в родной код для процессора, и только потом исполняется. По твоему определению это получается не-JIT.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Ну, да. Если без вариантов «сначала преобразуется в родной код для процессора, и только потом исполняется», то какой же это JIT? Это уже AOT.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

сначала преобразуется в родной код для процессора, и только потом исполняется

Другой вариант будет: сначала исполняется, а уже потом генерируется код. И это уже будет настоящий JIT? Я всё понял!

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Ить, вы двое глупые. Если программа сначала конпеляется, а потом запускается — это aot. Если сначала запускается, а потом конпеляется — это jit. Если запускается и не конпеляется — это интерпретатор.

Зовите, когда дойдёте до контейнеров против виртуальных машин.

anonymous
()
Ответ на: комментарий от anonymous

Если запускается и не конпеляется — это интерпретатор.

Питон «компиляется», но результат потом интерпретируется. Что ты на это скажешь, Эло Такседо Маск?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

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

anonymous
()
Ответ на: комментарий от anonymous

В Erlang/Elixir под hot code reloading понимают возможность накатить новую версию, не останавливая приложение и не теряя данные, которые есть у него в памяти, открытые сетевые соединения и пр.

theNamelessOne ★★★★★
()
Последнее исправление: theNamelessOne (всего исправлений: 1)
Ответ на: комментарий от theNamelessOne

В Erlang/Elixir под hot code reloading понимают возможность накатить новую версию, не останавливая приложение и не теряя данные, которые есть у него в памяти, открытые сетевые соединения и пр.

Ну, подобный механизм можно реализовать подгрузкой/выгрузкой динамических библиотек.

В Visual Studio под виндой для C/C++ есть механизм edit-and-continue или что-то в этом роде. Суть в том, что при отладке, остановившись на брекпойнте, ты мог подправить код и продолжить выполнение с измененным кодом. Как я понимаю, это реализовано следующим образом: в старом коде в нужное место вставляется jump на память, куда был помещен скомпилированный измененный кусок кода, в конце которого есть jump на оставшуюся часть старого кода.

Получается, что и у C++ есть hot code reloading, если сильно нужно.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.