zoukankan      html  css  js  c++  java
  • V8引擎简介——如何编译和执行JS代码

    1.用处

    • chrome浏览器的引擎
    • Nodejs的运行时环境
    • electron的底层引擎

    2.什么是V8引擎

    •  是用C++编写的Google开源高性能JS和WebAssembly引擎
    • 简而言之:是一个接收JS代码,编译代码然后执行的C++程序,编译后的代码可以在多种操作系统,多种处理器上运行

    主要的工作:

    1. 编译和执行JS代码
    2. 处理调用栈
    3. 内存的分配
    4. 垃圾的回收

    3.溯源

    大部分JS引擎在编译和执行JS代码都会用到三个重要的组件:

    • 解析器
      • 负责将JS源代码解析成抽象语法树AST
    • 解释器
      • 负责将AST解释成字节码bytecode
      • 也有直接解释执行bytecode的能力
    • 编译器
      • 负责编译出运行更加高效的机器代码

    早期的V8引擎是如何编译和执行JS代码的:

      在V8早期5.9版本之前,V8引擎没有解释器,却有两个编译器:

    • JS由解析器解析后,生成AST抽象语法树
    • 然后由编译器(Full-codegen)直接使用AST来编译出机器代码,而不进行任何中间转换
      • Full-codegen又称基准编译器,因为它生成的是一个基准的未被优化的机器代码
    • 还有另一个编译器(Crankshaft)——优化编译器:用来优化代码,提升性能

    缺陷:

    • 生成的机器码会占用大量的内存
    • 缺少中间的字节码,很多性能优化策略无法实施——V8性能提升缓慢
    • 无法很好的支持和优化JS的新语法特性

    4.目前的V8引擎

    • 网页初始化解析执行JS的时间缩短了,网页能够更快的onload
    • 在生成的优化机器代码时,不需要从源码重新编译,而使用字节码,并且当需要回退字节码时,只需要回归到中间层的字节码解释执行就可以了

    5.V8引擎中处理JS过程中的一些优化策略

    1. 如果函数只是声明而未被调用,则不会被解析生成AST
    2. 函数如果只被调用一次,bytecode直接被解释执行
    3. 函数被调用多次,可能会被标记为热点函数,可能会被编译成机器代码——提高代码的执行性能。
      1. 之后执行这个函数时,就直接运行优化后的机器代码 
      2. 随着JS代码的不断执行,会有更多的代码被标记为热点代码,也就会产生更多的机器代码
      3. 此时会有一个问题:回退字节码。
        1. 造成的原因是:如一个sum函数,参数是a,b,多次调用传入整数,且被识别为热点函数,解释器将收集到参数和函数信息编译成优化后的机器码,这里就会假定了sum函数的参数就是整形的
        2. 但是如果某次你传入的不是整数,而是字符串,机器不知道如何处理字符串类型的参数,此时就会deoptimization(回退字节码)
        3. 总结:不要把一个变量类型变来变去,传入的参数的类型也要固定一下
  • 相关阅读:
    jQuery基础之让出$,与其他库共存
    什么是闭包
    绑定repeater时三目运算加特殊结果处理
    将同一张表出来的两部分内容再合成一张表
    后台往前台写弹窗代码不显示
    固定行列转换加分段统计
    js调用后台方法(如果你能容忍执行的后台方法变成一个常量)
    javascript遍历数组
    基于SpringMVC框架使用ECharts3.0实现折线图,柱状图,饼状图,的绘制(上篇)
    echarts
  • 原文地址:https://www.cnblogs.com/codexlx/p/14179920.html
Copyright © 2011-2022 走看看