Ruby under Microscope
- code = <<STR
- ....
- STR
- Lexer:使用ripper
- pp Ripper.lex(code)
- pp Ripper.sexp(code)
- 2+2对应的YARV指令:
- putself
- putobject 2
- putobject 2
- opt_plus
- opt_send_simple <callinfo!mid:puts, argc:1...
- compile.c iseq_compile_each
- NODE_CALL
- NODE_FCALL
- NODE_VCALL
- RubyVM::InstructionSequence.compile(code).disasm
- The Local Table(局部变量、block参数等的符号查找表?)
- <Arg>
- <Rest> *args
- <Post> *args后面的参数
- <Block>
- <Opt=i> 默认参数
- YARV指令:putobject 5; setlocal 3(调用之前设置一下参数的值)
- YARV's internal stack
- 局部变量
- EP:special(向上层反向引用,用于动态查找) svar/cref(ep-1位置) local-vars ...
- 操作数优化:setlocal_OP_WC_0 相当于setlocal *, 0
- 方法参数相当于局部变量,差别只在于它是调用方push进栈的
- Dynamic Variable Access(访问外部的变量,闭包?)
- getlocal 2, 1 #后一个参数代表需要跳出的levels
- insns.def:for(i=0; i<lev; i++) ep=GET_PREV_EP(ep); val=*(ep-idx);
- 特殊变量($开头的一些
全局变量)- $*=ARGV $!=上个异常 $&=上个正则匹配结果(动态作用域,不是文法作用域?) ...
- p79 其他的:$$=pid $?=last_status $!/$@=error $/$\$;$, $= $:=load_path $< $> $"
- 文法作用域用于常量查找?
- $*=ARGV $!=上个异常 $&=上个正则匹配结果(动态作用域,不是文法作用域?) ...
- 控制结构与方法分发
- YARV branchif/branchunless/jump
- throw(对应代码块中的break/return语句):跳出当前的scope
- Catch Table:也用于实现rescue/ensure/retry/redo/next
- Ruby中for循环只是each的语法糖?
- send:
- Method lookup
- Method dispatch
- Ruby方法的11种类型:ISEQ & CFUNC ATTRSET IVAR BMETHOD ZSUPER UNDEF NOTIMPLEMENTED OPTIMIZED MISSING REFINED
- ISEQ参数类型:&block、optional=default_value、*splat_arg_array、post arguments
- CFUNC:创建一个新stack frame
- attr_reader(IVAR)与attr_writer(ATTRSET)
- 关键字参数:使用Hash#key?
- RObject:klass+numiv/ivptr(实例变量)
- RString/RArray/RRegexp :RBasic
- 实例变量性能测试:Class.new.new => 1.8使用通用hashtable,1.9&2.0引入数组(对应的名字保存在class里)
- RClass:method table+attribute names
- class-level instance vars
- superclass
- Class Instance Vars@ vs. Class Vars@@ --保存在同样的table中?
- 对类变量,最高的基类优先(子类的RClass是否会冗余存储?)
- 常量(必须以大写字母开头):const_tbl
- 其他:origin(用于Module#prepend)、refined_class、allocator(定制对象池?)
- class方法:notsaved!
- ObjectSpace.count_objects[:T_CLASS] ==> metaclass(即klass指向的对象)
- MyClass.singleton_class
- 方法查找与常量查找
- Modules Are Classes
- 不能创建对象、不能指定superclass
- 可在class中include module(插入一个RClass副本到类的superclass单链表!)~extend
- Ruby不支持C++那样的多继承?
- 注意:module对应的RClass数据结构在include到class时是(浅)copy的,但module的方法却是共享的!
- 方法查找:遍历superclass链
- include多个module时,后面的优先查找!--> module本身可以嵌套include!(这种情况下保持了查找顺序)
- 2.0 Module#prepend(即include关键字改为prepend)
- origin/super
- The Global/Inline Method Cache
- e.g. Fixnum#times --> Integer#times
- inline-cache是第2次执行时的优化(这要求动态修改指令序列)
- 常量查找
- Finding constant in a Superclass(same as method)
- Finding constant in Parent Namespace?Lexical Scope(此操作优先)
- cref?:nd_next/nd_clss(名字命名真垃圾)
- Rails autoload
- const_missing
- Modules Are Classes
- The Hash Table
- 一旦density超过,Rehashing Entries(扩大桶(bin?)基数)
- p177 进行benchmark时GC.disable?
- 1.9 & 2.0 MurmurHash
- 重载hash与eql?
- 1.9 & 2.0 小Hash优化(小于6个元素):packed hashes
- Blocks: Closures in Ruby
- rb_block_t:iseq EP
- rb_control_frame_t内部嵌套包含了rb_block_t,因此创建块时不需要malloc,直接引用其内部数据结构...
- while vs each
- rb_block_t:iseq EP
- Lambdas and Procs
- lambda do ... end:把block转换为数据(first-class citizen),然后可在上调用:<lo>.call(args)
- 当调用lambda,Ruby将当前的整个YARV栈内容复制到堆中,并创建2个新对象:
- rb_env_t
- rb_proc_t(lambda返回的proc对象)
- is_lambda=true
- Proc:RTypedData
- lambda栈copy后,Ruby将更新EP指向堆上的新栈???(有点对call stack进行MVCC snapshot的感觉)
- 多次lambda栈copy呢?
- Ruby检查EP是否已经指向堆,是,则不重复copy(什么???这种行为很怪异)
- 多次lambda栈copy呢?
- 元编程
- 不同的Define Methods
- 类方法(def self.xxx ...):加入到metaclass里
- 类方法,使用新文法作用域(即其metaclass,class < self def xxx ...)
- 实例方法,使用单例类:def someObj. method ...
- 所有的metaclasses是singleton classes,反之不成立
- class << someObj ... end
- 2.0 refinements(类似于Erlang的Hotfix?):定义方法,但可以在以后添加到类中
- module SomeRefine refine SomeClass do ...end end --> using SomeRefine
- 当前只允许在top-level scope中使用(using是顶级main对象的方法,p self)
- self
- eval、instance_eval、binding
- a binding is a closure without a function, just the ref environment.(持久化到heap)
- instance_eval changes self to the Receiver
- instance_eval creates a Singleton Class for a New Lexical Scope
- define_method :method_name do ... end
- SomeClassA.send(:define_method, :method_name) do ... end
- 不同的Define Methods
- JRuby
- p Class.ancestors
- => [Class, Module, Object, Kernel, BasicObject]
- -J-XX:+PrintCompilation
- 对热点代码可用上JVM的JIT优化
- String表示:RubyString -> ByteList
- Copy-on-Write
- p Class.ancestors
- Rubinius:Ruby in Ruby(用语言本身实现语言,更小的子集,层次化的优化考虑?)
- Kernel(in Ruby)+VM(in C++?)=> LLVM
- $ rbx compile simple.rb -B
- backtrace:相比于MRI,显示更多的信息
- 实例分析:Array#shift
- GC
- MRI:Mark and Sweep
- bitmap marking
- Lazy Sweeping(并发+增量式?)
- RVALUE
- Copying GC(只有active对象才会被copy,垃圾直接被丢弃)
- Bump Allocation(在一块大空间中顺序分配小块?)
- The Semi-Space Algorithm(麻烦的地方:必须更新引用)
- 变体:The Eden Heap(存储新分配的对象?每次GC都重新copy出去?)
- Generational GC
- The Weak Generational Hypothesis:new objects are likely to die young.
- Concurrent GC
- Tricolor Marking(这术语真是莫名其妙!)
- JVM:Serial,Parallel,Concurrent;G1,C4
- MRI:Mark and Sweep