现在的位置: 首页 > 综合 > 正文

Ruby under Microscope 笔记

2016年07月28日 ⁄ 综合 ⁄ 共 4211字 ⁄ 字号 评论关闭

Ruby under Microscope

跳转至:
导航

搜索
  1. code = <<STR

    ....
    STR
  2. Lexer:使用ripper
    1. pp Ripper.lex(code)
    2. pp Ripper.sexp(code)
  3. 2+2对应的YARV指令:
    1. putself
    2. putobject 2
    3. putobject 2
    4. opt_plus
    5. opt_send_simple <callinfo!mid:puts, argc:1...
  4. compile.c iseq_compile_each
    1. NODE_CALL
    2. NODE_FCALL
    3. NODE_VCALL
  5. RubyVM::InstructionSequence.compile(code).disasm
  6. The Local Table(局部变量、block参数等的符号查找表?)
    1. <Arg>
    2. <Rest> *args
    3. <Post> *args后面的参数
    4. <Block>
    5. <Opt=i> 默认参数
      1. YARV指令:putobject 5; setlocal 3(调用之前设置一下参数的值)
  7. YARV's internal stack
    1. rb_control_frame_t, pc, sp, self, type
    2. Call stack:<TOP> <EVAL> <CFUNC>(int_dotimes) <BLOCK>
    3. C code:insns.def --> Miniruby(编译为更小的子集?类似于Haskell/ML) -->

      vm.inc
  8. 局部变量
    1. EP:special(向上层反向引用,用于动态查找) svar/cref(ep-1位置) local-vars ...
    2. 操作数优化:setlocal_OP_WC_0 相当于setlocal *, 0
    3. 方法参数相当于局部变量,差别只在于它是调用方push进栈的
  9. Dynamic Variable Access(访问外部的变量,闭包?)
    1. getlocal 2, 1 #后一个参数代表需要跳出的levels
    2. insns.def:for(i=0; i<lev; i++) ep=GET_PREV_EP(ep); val=*(ep-idx);
  10. 特殊变量($开头的一些全局变量)
    1. $*=ARGV $!=上个异常 $&=上个正则匹配结果(动态作用域,不是文法作用域?) ...

      1. p79 其他的:$$=pid $?=last_status $!/$@=error $/$\$;$, $= $:=load_path $< $> $"
    2. 文法作用域用于常量查找?
  11. 控制结构与方法分发
    1. YARV branchif/branchunless/jump
    2. throw(对应代码块中的break/return语句):跳出当前的scope
      1. Catch Table:也用于实现rescue/ensure/retry/redo/next
    3. Ruby中for循环只是each的语法糖?
    4. send
      1. Method lookup
      2. Method dispatch
    5. Ruby方法的11种类型:ISEQ & CFUNC ATTRSET IVAR BMETHOD ZSUPER UNDEF NOTIMPLEMENTED OPTIMIZED MISSING REFINED
      1. ISEQ参数类型:&block、optional=default_value、*splat_arg_array、post arguments
      2. CFUNC:创建一个新stack frame
      3. attr_reader(IVAR)与attr_writer(ATTRSET)
      4. 关键字参数:使用Hash#key?
  12. RObject:klass+numiv/ivptr(实例变量)
    1. RString/RArray/RRegexp :RBasic
    2. 实例变量性能测试:Class.new.new => 1.8使用通用hashtable,1.9&2.0引入数组(对应的名字保存在class里)
  13. RClass:method tableattribute names
    1. class-level instance vars
    2. superclass
    3. Class Instance Vars@ vs. Class Vars@@ --保存在同样的table中?
      1. 对类变量,最高的基类优先(子类的RClass是否会冗余存储?)
    4. 常量(必须以大写字母开头):const_tbl
    5. 其他:origin(用于Module#prepend)、refined_classallocator(定制对象池?)
    6. class方法:notsaved!
      1. ObjectSpace.count_objects[:T_CLASS] ==> metaclass(即klass指向的对象)
      2. MyClass.singleton_class
  14. 方法查找与常量查找
    1. Modules Are Classes

      1. 不能创建对象、不能指定superclass
      2. 可在class中include module(插入一个RClass副本到类的superclass单链表!)~extend
        1. Ruby不支持C++那样的多继承?
        2. 注意:module对应的RClass数据结构在include到class时是(浅)copy的,但module的方法却是共享的!
    2. 方法查找:遍历superclass链
      1. include多个module时,后面的优先查找!--> module本身可以嵌套include!(这种情况下保持了查找顺序)
      2. 2.0 Module#prepend(即include关键字改为prepend)
        1. origin/super
    3. The Global/Inline Method Cache
      1. e.g. Fixnum#times --> Integer#times
      2. inline-cache是第2次执行时的优化(这要求动态修改指令序列)
    4. 常量查找
      1. Finding constant in a Superclass(same as method)
      2. Finding constant in Parent Namespace?Lexical Scope(此操作优先)
        1. cref?:nd_next/nd_clss(名字命名真垃圾)
      3. Rails autoload
      4. const_missing
  15. The Hash Table
    1. 一旦density超过,Rehashing Entries(扩大桶(bin?)基数)
    2. p177 进行benchmark时GC.disable
    3. 1.9 & 2.0 MurmurHash
    4. 重载hash与eql?
      1. 1.9 & 2.0 小Hash优化(小于6个元素):packed hashes
  16. Blocks: Closures in Ruby
    1. rb_block_t:iseq EP

      1. rb_control_frame_t内部嵌套包含了rb_block_t,因此创建块时不需要malloc,直接引用其内部数据结构...
    2. while vs each
  17. Lambdas and Procs
    1. lambda do ... end:把block转换为数据(first-class citizen),然后可在上调用:<lo>.call(args)
    2. 当调用lambda,Ruby将当前的整个YARV栈内容复制到堆中,并创建2个新对象:
      1. rb_env_t
      2. rb_proc_t(lambda返回的proc对象)
        1. is_lambda=true
    3. Proc:RTypedData
    4. lambda栈copy后,Ruby将更新EP指向堆上的新栈???(有点对call stack进行MVCC snapshot的感觉)
      1. 多次lambda栈copy呢?

        1. Ruby检查EP是否已经指向堆,是,则不重复copy(什么???这种行为很怪异)
  18. 元编程
    1. 不同的Define Methods

      1. 类方法(def self.xxx ...):加入到metaclass里
      2. 类方法,使用新文法作用域(即其metaclass,class < self def xxx ...)
      3. 实例方法,使用单例类:def someObj. method ...
        1. 所有的metaclasses是singleton classes,反之不成立
        2. class << someObj ... end
    2. 2.0 refinements(类似于Erlang的Hotfix?):定义方法,但可以在以后添加到类中
      1. module SomeRefine refine SomeClass do ...end end --> using SomeRefine
      2. 当前只允许在top-level scope中使用(using是顶级main对象的方法,p self
    3. self
    4. eval、instance_eval、binding
      1. a binding is a closure without a function, just the ref environment.(持久化到heap)
      2. instance_eval changes self to the Receiver
      3. instance_eval creates a Singleton Class for a New Lexical Scope
      4. define_method :method_name do ... end
        1. SomeClassA.send(:define_method, :method_name) do ... end
  19. JRuby
    1. p Class.ancestors

      1. => [Class, Module, Object, Kernel, BasicObject]
    2. -J-XX:+PrintCompilation
      1. 对热点代码可用上JVM的JIT优化
    3. String表示:RubyString -> ByteList
    4. Copy-on-Write
  20. Rubinius:Ruby in Ruby(用语言本身实现语言,更小的子集,层次化的优化考虑?)
    1. Kernel(in Ruby)+VM(in C++?)=> LLVM
    2. $ rbx compile simple.rb -B
    3. backtrace:相比于MRI,显示更多的信息
    4. 实例分析:Array#shift
  21. GC
    1. MRI:Mark and Sweep

      1. bitmap marking
      2. Lazy Sweeping(并发+增量式?)
      3. RVALUE
    2. Copying GC(只有active对象才会被copy,垃圾直接被丢弃)
      1. Bump Allocation(在一块大空间中顺序分配小块?)
      2. The Semi-Space Algorithm(麻烦的地方:必须更新引用)
        1. 变体:The Eden Heap(存储新分配的对象?每次GC都重新copy出去?)
    3. Generational GC
      1. The Weak Generational Hypothesis:new objects are likely to die young.
    4. Concurrent GC
      1. Tricolor Marking(这术语真是莫名其妙!)
      2. JVM:Serial,Parallel,Concurrent;G1,C4 

抱歉!评论已关闭.