Как я могу увидеть машинный код, сгенерированный v8?

Кто-нибудь знает, как я могу увидеть фактический машинный код, который v8 генерирует из Javascript? Я добрался до Script::Compile() в src/api.cc, но я не могу понять, куда дальше идти.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
25
0
10 849
5

Ответы 5

Думаю, ты на правильном пути.

Похоже, вам нужно перейти от Script :: Compile к Compiler :: Compile, что приведет вас к генераторам кода (codegen * .cc и .h).

Все это означает, что, глядя на codegen-ia32.cc, если вы определите ENABLE_DISASSEMBLER я думаю, когда вы строите, ваша разборка должна быть распечатана.

Конечно, все это просто от быстрого просмотра старой копии источника, который у меня есть, так что YMMV, но я думаю, что это должно сработать.

(Посмотрев на ваш пост еще раз, я вижу, что вы ищете машинный язык, а не ассемблер - я не уверен, но вам, возможно, придется изменить логику, если вы хотите вывод собранного кода, а не его разборку)

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

Сначала скомпилируйте v8 с поддержкой дизассемблера:

scons [your v8 build options here] disassembler=on sample=shell

Теперь вы можете вызвать оболочку с параметром «--print_code»:

./shell --print_code hello.js

Что должно дать вам что-то вроде этого:

--- Raw source ---
print("hello world");

--- Code ---
kind = FUNCTION
Instructions (size = 134)
0x2ad0a77ceea0     0  55             push rbp
0x2ad0a77ceea1     1  488bec         REX.W movq rbp,rsp
0x2ad0a77ceea4     4  56             push rsi
0x2ad0a77ceea5     5  57             push rdi
0x2ad0a77ceea6     6  49ba59c13da9d02a0000 REX.W movq r10,0x2ad0a93dc159    ;; object: 0xa93dc159 <undefined>
0x2ad0a77ceeb0    16  4952           REX.W push r10
0x2ad0a77ceeb2    18  49ba688b700000000000 REX.W movq r10,0x708b68
0x2ad0a77ceebc    28  493b22         REX.W cmpq rsp,[r10]
0x2ad0a77ceebf    31  0f824e000000   jc 115  (0x2ad0a77cef13)
0x2ad0a77ceec5    37  488b462f       REX.W movq rax,[rsi+0x2f]
0x2ad0a77ceec9    41  4883ec18       REX.W subq rsp,0xlx
0x2ad0a77ceecd    45  49ba094b3ea9d02a0000 REX.W movq r10,0x2ad0a93e4b09    ;; object: 0xa93e4b09 <String[5]: print>
0x2ad0a77ceed7    55  4c8955e0       REX.W movq [rbp-0x20],r10
0x2ad0a77ceedb    59  488945d8       REX.W movq [rbp-0x28],rax
0x2ad0a77ceedf    63  49ba014d3ea9d02a0000 REX.W movq r10,0x2ad0a93e4d01    ;; object: 0xa93e4d01 <String[11]: hello world>
0x2ad0a77ceee9    73  4c8955d0       REX.W movq [rbp-0x30],r10
0x2ad0a77ceeed    77  49baa06c7ba7d02a0000 REX.W movq r10,0x2ad0a77b6ca0    ;; debug: statement 0
                                 ;; code: contextual, CALL_IC, UNINITIALIZED, argc = 1
0x2ad0a77ceef7    87  49ffd2         REX.W call r10
0x2ad0a77ceefa    90  488b75f8       REX.W movq rsi,[rbp-0x8]
0x2ad0a77ceefe    94  4883c408       REX.W addq rsp,0xlx
0x2ad0a77cef02    98  488945e8       REX.W movq [rbp-0x18],rax
0x2ad0a77cef06   102  488be5         REX.W movq rsp,rbp      ;; js return
0x2ad0a77cef09   105  5d             pop rbp
0x2ad0a77cef0a   106  c20800         ret 0x8
0x2ad0a77cef0d   109  cc             int3
0x2ad0a77cef0e   110  cc             int3
0x2ad0a77cef0f   111  cc             int3
0x2ad0a77cef10   112  cc             int3
0x2ad0a77cef11   113  cc             int3
0x2ad0a77cef12   114  cc             int3
0x2ad0a77cef13   115  49ba60657ba7d02a0000 REX.W movq r10,0x2ad0a77b6560    ;; code: STUB, StackCheck, minor: 0
0x2ad0a77cef1d   125  49ffd2         REX.W call r10
0x2ad0a77cef20   128  488b7df0       REX.W movq rdi,[rbp-0x10]
0x2ad0a77cef24   132  eb9f           jmp 37  (0x2ad0a77ceec5)

RelocInfo (size = 10)
0x2ad0a77ceea8  embedded object  (0xa93dc159 <undefined>)
0x2ad0a77ceecf  embedded object  (0xa93e4b09 <String[5]: print>)
0x2ad0a77ceee1  embedded object  (0xa93e4d01 <String[11]: hello world>)
0x2ad0a77ceeed  statement position  (0)
0x2ad0a77ceeef  code target (context) (CALL_IC)  (0x2ad0a77b6ca0)
0x2ad0a77cef06  js return
0x2ad0a77cef15  code target (STUB)  (0x2ad0a77b6560)

hello world

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

Вам нужно собрать v8 с поддержкой дизассемблера.

Загрузите исходный код v8.

git clone https://chromium.googlesource.com/v8/v8.git

Сборка с поддержкой дизассемблера.

make dependencies
make ia32.release objectprint=on disassembler=on

Вызовите d8 (оболочка v8), используя определенные флаги, в зависимости от того, что вы хотите.

out/ia32.release/d8 --code-comments --print-code <app.js>

Для справки:

  • --code-комментарии: включает комментарии к коду.
  • --печатный код: выводит код на стандартный вывод.
  • --печать-код-заглушки: печатает заглушки кода.
  • --print-opt-code: печатает оптимизированный код.
  • - следовой водород: печатает код IR (промежуточное представление) в Hydrogen.cfg. Этот файл можно открыть с помощью Java C1Visualizer.

все эти параметры недействительны в новейшей версии V8, не могли бы вы обновить свой ответ, чтобы отразить новейшие аргументы?

James Yang 14.03.2018 04:48

Извини, я не могу. Я больше не работаю над V8, поэтому не знаю, как называются новейшие аргументы. Это нормально, что со временем ответы устареют. Если другой пользователь хочет опубликовать новый ответ с более актуальным ответом, конечно, он может это сделать (и наверняка получит несколько баллов).

Diego Pino 14.03.2018 15:13

Взгляните на v8_root/build/features.gypi, и вы найдете связанные с дизассемблером и многие другие переключатели функций времени компиляции для V8.

Попробуйте с NodeJS или Chrome:

  1. -print-opt-code: код, созданный оптимизирующим компилятором.
  2. -print-bytecode: байтовый код, генерируемый интерпретатором.
  3. -trace-opt и -trace-depot: какие функции (де) оптимизированы.

Проверьте эту статью @Franziska Hinkelmann:

https://medium.com/dailyjs/understanding-v8s-bytecode-317d46c94775

Дополнительно вы также можете попробовать

D8: он поможет вам скомпилировать V8 и просмотреть код сборки, сгенерированный из JavaScript.

Для использования и подробностей:

http://www.mattzeunert.com/2015/08/19/viewing-assembly-code-generated-by-v8.html

Спасибо! Это действительно здорово!

devwannabe 27.06.2019 16:06

Другие вопросы по теме