【问题标题】:Why does JavaScript get compiled to machine code?为什么 JavaScript 会被编译成机器码?
【发布时间】:2020-09-26 02:13:44
【问题描述】:

我最近开始了一些 Web 开发,使用 ASP.NET 和一些 Javascript,有些事情让我很困惑。

我总是读到,JavaScript 过去常常被解释,直到 JIT 慢慢地把它编译成机器代码(这使得浏览器更快)。

这对我来说毫无意义。如果传统的 JavaScript 应用程序一开始不以机器/CPU 为目标,JavaScript 如何编译为本机机器码?

我了解是否使用 NodeJS 运行时将 electron.js 应用程序编译为机器代码。我明白了。因为它本机编译为机器代码,据我了解,不能在浏览器中运行

如果传统的 JavaScript 应用程序在浏览器中运行,为什么必须将其编译为机器码?浏览器负责运行代码,而不是 CPU。 CPU 运行浏览器本身。我实际上根本看不到本机操作系统如何影响浏览器中发生的任何事情,反之亦然。似乎也是一个安全问题。

对不起,如果这是一个愚蠢的问题,但我找不到任何可以说“Javascript 使用 JIT”的资源

谢谢!

劳伦

【问题讨论】:

标签: javascript compilation jit machine-code


【解决方案1】:

最终,CPU 必须运行代码。

JIT 将其编译为机器码是一种加快速度的方法。

如果传统的 JavaScript 应用程序一开始不以机器/CPU 为目标,JavaScript 如何编译为本机机器码?

不是“Javascript”在做它,它是浏览器(或者更确切地说,是浏览器内的 Javascript 执行引擎),并且由于它是“JIT”,它确切地知道要定位哪个 CPU(这没有完成一般而言,这是针对浏览器当前运行的特定 CPU 完成的)。

所以,是的,存在一些不匹配,因为 Javascript 不会使用 CPU 可以直接使用的低级原始类型,这就是为什么存在大量间接和推测类型推断猜测工作的原因。生成的机器代码与您从手动编码的汇编中获得的代码有很大不同,但它仍然可以是净正面的。为了解决这个问题,开发了更接近“正常”机器代码的 WASM。

其他中间的、非 CPU 特定的格式,如 JVM 字节码或 CLR 字节码或 LLVM 位码也处于类似的情况(在这种情况下,它们也可以编译为它们本身不直接定位的机器代码)——但它们已经“降低了” " 已经从语言源代码变成了接近机器代码的东西。

似乎也是一个安全问题。

是的,可以。浏览器在这里所​​做的事情必须小心,并且操作系统应该尽可能地对浏览器进行沙箱处理。

【讨论】:

    【解决方案2】:

    执行指令比运行解释器更容易,JIT 试图利用这一点来提高性能。在您计算机上运行的所有程序在某些时候都会变成机器代码,唯一的问题是执行哪些指令。

    let x=0;
    for (let i=0;i<100;++i) {
      x+=2;
    }
    

    由于很明显这样的代码块没有副作用,所以直接编译指令而不是解释每一行代码会更快。

    // NIOS 2 assembly, sorry its the only one i know
    movi r2,0
    movi r3,0
    movi r4,100
    loop:
      addi r2,2
      addi r3,1
      blt r3,r4,loop
    

    执行此操作将比执行每个单独指令的解析逻辑更快。

    TLDR:所有程序始终运行 CPU 指令,因此通过尽可能跳过解析阶段来最大限度地减少指令数量会更快

    【讨论】:

    • 请注意,Javascript 最大的复杂之处在于 JIT 编译器必须确定 x 是否可以是本机整数类型(然后直接放入 CPU 寄存器并与 @987654324 一起使用@) 或者如果它需要更多的工作。 Javascript 没有声明类型,你可以在下一行做x = x*2.87 甚至x = "Hello"。使用 JVM 字节码或 WASM 之类的东西,至少有精确的输入。
    猜你喜欢
    • 2015-01-30
    • 1970-01-01
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    • 1970-01-01
    • 2015-05-11
    • 1970-01-01
    相关资源
    最近更新 更多