├── DartVM ├── src │ ├── out │ │ ├── bootstrap_natives.h │ │ ├── fibo.dart │ │ ├── fibo.main.ir │ │ ├── fibo.fibo.a1.ir │ │ ├── fibo.clang32.asm │ │ ├── fibo.fibo.ir │ │ ├── fibo.main.asm │ │ ├── fibo.fibo.a2.ir │ │ └── fibo.java7.asm │ ├── png │ │ ├── dart.png │ │ ├── dart_bench.png │ │ ├── dart_object.png │ │ ├── dart_optimize.png │ │ ├── dart_rawobject.png │ │ ├── inherit_graph.png │ │ ├── perf_aobench.png │ │ └── perf_aobench_notgen.png │ ├── int_double.rst │ ├── advent201212todo.rst │ ├── finalizer.rst │ ├── googleio2013.rst │ ├── lock.rst │ ├── advent20131201.rst │ ├── sdk │ │ └── stream.rst │ ├── advent2013120x.rst │ ├── pub.rst │ ├── devmember.rst │ ├── stubs.rst │ ├── future.rst │ ├── performance.rst │ ├── inlinecache.rst │ ├── speedup.rst │ ├── dart_io.rst │ ├── v8_speedup.rst │ ├── optimizer.rst │ ├── message_handler.rst │ ├── external.rst │ ├── base.rst │ ├── deopt3.rst │ ├── stream.rst │ ├── os.rst │ ├── advent201212index.rst │ ├── storebarrier.rst │ ├── vmservice.rst │ ├── osr.rst │ ├── specialize.rst │ ├── advent20121201.rst │ ├── string.rst │ ├── start.rst │ ├── regalloc.rst │ ├── thread.rst │ ├── advent20121208.rst │ ├── advent20121202.rst │ ├── fix_todo.rst │ ├── async.rst │ ├── inlining.rst │ ├── advent20121218.rst │ ├── memory.rst │ ├── eventloop.rst │ ├── advent20121209.rst │ ├── advent20121205.rst │ └── branch.rst ├── index.rst └── _templates │ └── layout.html ├── Ethereum ├── todo.rst ├── contract.rst ├── cmd.rst ├── overview.rst └── asm.rst ├── OpenJDK ├── bench │ ├── setenv.sh │ ├── Makefile │ ├── run.sh │ ├── README │ ├── DeserBenchmark.java │ └── deser_benchmark.c ├── print.rst ├── numa.rst └── wb.rst ├── erlang ├── release17.rst ├── aio.rst ├── erlang_overview.rst ├── todo.rst └── reference.rst ├── golang ├── thread.rst ├── src.rst ├── base.rst ├── async.rst ├── todo.rst ├── gephi.rst ├── overview.rst ├── syscall.rst ├── goroutine.rst ├── deadlock.rst ├── json.rst ├── resource.rst ├── cc.rst ├── runtime.rst ├── memory.rst ├── compiler.rst ├── cmd.rst └── garbage_collection.rst ├── Pyston ├── src.rst ├── base.rst ├── overview.rst └── 0_1.rst └── art ├── profile.rst ├── quick.rst ├── unit.rst ├── overview.rst ├── todo.rst ├── gc.rst ├── optimize.rst └── log.rst /DartVM/src/out/bootstrap_natives.h: -------------------------------------------------------------------------------- 1 | /home/elise/language/dart/edge/vm/bootstrap_natives.h -------------------------------------------------------------------------------- /DartVM/src/png/dart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nothingcosmos/VM/HEAD/DartVM/src/png/dart.png -------------------------------------------------------------------------------- /DartVM/src/png/dart_bench.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nothingcosmos/VM/HEAD/DartVM/src/png/dart_bench.png -------------------------------------------------------------------------------- /DartVM/src/png/dart_object.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nothingcosmos/VM/HEAD/DartVM/src/png/dart_object.png -------------------------------------------------------------------------------- /DartVM/src/png/dart_optimize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nothingcosmos/VM/HEAD/DartVM/src/png/dart_optimize.png -------------------------------------------------------------------------------- /DartVM/src/png/dart_rawobject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nothingcosmos/VM/HEAD/DartVM/src/png/dart_rawobject.png -------------------------------------------------------------------------------- /DartVM/src/png/inherit_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nothingcosmos/VM/HEAD/DartVM/src/png/inherit_graph.png -------------------------------------------------------------------------------- /DartVM/src/png/perf_aobench.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nothingcosmos/VM/HEAD/DartVM/src/png/perf_aobench.png -------------------------------------------------------------------------------- /DartVM/src/png/perf_aobench_notgen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nothingcosmos/VM/HEAD/DartVM/src/png/perf_aobench_notgen.png -------------------------------------------------------------------------------- /Ethereum/todo.rst: -------------------------------------------------------------------------------- 1 | todo / 課題 2 | ######################## 3 | 4 | vmの実行モデルを整理し、opcodeを読めるように 5 | 6 | smartcontractの実装を理解する 7 | 8 | 9 | -------------------------------------------------------------------------------- /DartVM/src/int_double.rst: -------------------------------------------------------------------------------- 1 | // TODO: Convert this abstract class into a concrete class double 2 | // that uses the patch class functionality to account for the 3 | // different platform implementations. 4 | 5 | 6 | -------------------------------------------------------------------------------- /DartVM/src/advent201212todo.rst: -------------------------------------------------------------------------------- 1 | Dart VM Advent Calendar todo 2 | ############################################################################### 3 | 4 | 1. hotcodeのしきい値が2000から3000に変更されている。 5 | https://codereview.chromium.org//11442059 6 | 7 | -------------------------------------------------------------------------------- /OpenJDK/bench/setenv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export PATH=/home/elise/language/java/openjdk/jdk8/build/linux-x86_64-normal-server-fastdebug/jdk/bin:$PATH 4 | #export PATH=/home/elise/language/java/openjdk/jdk8/build/linux-x86_64-normal-server-release/jdk/bin:$PATH 5 | -------------------------------------------------------------------------------- /DartVM/src/out/fibo.dart: -------------------------------------------------------------------------------- 1 | int fibo(int n) { 2 | if (n < 2) { 3 | return n; 4 | } else { 5 | return fibo(n - 1) + fibo(n - 2); 6 | } 7 | } 8 | 9 | main() { 10 | fibo(40); 11 | } 12 | 13 | $ dart fibo.dart 14 | 102334155 15 | ret = 903 ms 16 | 17 | -------------------------------------------------------------------------------- /Ethereum/contract.rst: -------------------------------------------------------------------------------- 1 | Smart Contract 2 | ####### 3 | 4 | Contract Creation 5 | https://y-nakajo.hatenablog.com/entry/2018/05/17/100752 6 | 7 | inputデータを保存する前に、コンストラクタを実行するらしい 8 | 9 | ABI 10 | ######## 11 | https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI 12 | -------------------------------------------------------------------------------- /erlang/release17.rst: -------------------------------------------------------------------------------- 1 | A new (optional) scheduler utilization balancing mechanism 2 | Migration of memory carriers has been enabled by default on all ERTS internal memory allocators 3 | Increased garbage collection tenure rate 4 | Experimental "dirty schedulers" functionality 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /DartVM/src/finalizer.rst: -------------------------------------------------------------------------------- 1 | vm/class_finalizerは、いつ呼ばれるのか。 2 | class loadingの直後? 3 | 4 | Class finalization occurs: 5 | // a) when bootstrap process completes (VerifyBootstrapClasses). 6 | // b) after the user classes are loaded (dart_api). 7 | 8 | // compiled 9 | 10 | 11 | after compile, before install 12 | -------------------------------------------------------------------------------- /DartVM/src/out/fibo.main.ir: -------------------------------------------------------------------------------- 1 | ==== file:///home/elise/language/dart/work/adven/fibo.dart_::_main 2 | B0[graph] 3 | B1[target] 4 | 5 | //prolog 6 | CheckStackOverflow:2() 7 | //body 8 | t0 <- Constant:3(#40) 9 | PushArgument:4(t0) 10 | StaticCall:5(fibo t0) 11 | //epilog 12 | t0 <- Constant:6(#null) 13 | Return:7(t0) 14 | 15 | -------------------------------------------------------------------------------- /golang/thread.rst: -------------------------------------------------------------------------------- 1 | 2 | goのthread生成のタイミング 3 | 4 | threadはruntimeとruntime/cgo周り 5 | 6 | newm() { 7 | asmcall(_cgo_thread_start, xxx); 8 | } 9 | 10 | 11 | 基本はこれかな。 12 | 13 | 呼び出し条件を見てみる 14 | 15 | newm経由でthreadが呼び出されるパターンを洗い出す 16 | すべてruntime/proc 17 | 18 | startm -> newm 19 | 20 | handoffp -> startm 21 | 22 | wakep -> startm 23 | 24 | injectglist -> startm 25 | 26 | 結構制限なくstartmを呼び出すのかな? 27 | -------------------------------------------------------------------------------- /DartVM/src/googleio2013.rst: -------------------------------------------------------------------------------- 1 | Web Languages and VMs 2 | Modern Web Engine Technology 3 | 4 | DOM code cannnot have cycles 5 | 6 | V8に口をつくって、DOMから参照する。 7 | 口からはweak referenceで参照する。 8 | 9 | Hidden classes 10 | State-of-the-art adaptive compilation 11 | Sophisticated memory management 12 | 13 | Tracing GC tangoing with reference counting by google 14 | 15 | Richards 16 | DeltaBlue 17 | 18 | Oilpan A unified memory manager for Blink 19 | DOM 20 | 21 | 22 | -------------------------------------------------------------------------------- /OpenJDK/bench/Makefile: -------------------------------------------------------------------------------- 1 | all: run 2 | 3 | DeserBenchmark.class: DeserBenchmark.java 4 | javac DeserBenchmark.java 5 | 6 | deser_benchmark: deser_benchmark.c 7 | gcc -Wall deser_benchmark.c --std=c99 -O2 -DLOOP=1000 -o deser_benchmark 8 | 9 | run: DeserBenchmark.class deser_benchmark 10 | java -cp . DeserBenchmark 1700461846 10000000 1000 11 | ./deser_benchmark 12 | 13 | clean: 14 | rm -f *.class 15 | rm -f random.data 16 | rm -f deser_benchmark 17 | 18 | .PHONY: clean run 19 | -------------------------------------------------------------------------------- /Ethereum/cmd.rst: -------------------------------------------------------------------------------- 1 | cmd 2 | ########################### 3 | 4 | cmdから主制御部分を把握できるようにする 5 | 6 | まずはgethから 7 | 8 | 9 | var 10 | app = utils.NewApp() 11 | 12 | init 13 | appの初期化 14 | Action = geth //main entry point 15 | 16 | 17 | main 18 | app.Run() 19 | //geth 20 | node := makeFullNode(ctx) 21 | startNode(ctx, node) 22 | StartNode(node) 23 | ethereum.StartMining() 24 | node.Wait() 25 | 26 | 27 | 28 | rpc 29 | ################### 30 | 31 | jsonRPC 32 | 33 | method, jsonrpc, id,params 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /DartVM/src/lock.rst: -------------------------------------------------------------------------------- 1 | platform 2 | ############################################################################### 3 | 4 | platform independent platform/thread.h 5 | 6 | Thread 7 | Mutex 8 | Monitor 9 | 10 | 11 | =============================================================================== 12 | 13 | =============================================================================== 14 | 15 | =============================================================================== 16 | =============================================================================== 17 | -------------------------------------------------------------------------------- /OpenJDK/bench/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #jit="-XX:+TieredCompilation" 4 | jit="-server -Xbatch" 5 | unlock="-XX:+UnlockDiagnosticVMOptions" 6 | asm="-XX:+PrintOptoAssembly" 7 | #inline="-XX:MaxInlineSize=1 -XX:FreqInlineSize=1" 8 | compile="-XX:+PrintCompilation -XX:+PrintInlining" 9 | #deopt="-XX:+TraceDeoptimization -XX:+DebugDeoptimization" 10 | 11 | #base java -cp . DeserBenchmark 1700461846 10000000 1000 12 | 13 | java -version 14 | java -cp . $jit $unlock $inline $asm $compile $deopt DeserBenchmark 1700461846 10000000 100 15 | java -version 16 | 17 | -------------------------------------------------------------------------------- /DartVM/index.rst: -------------------------------------------------------------------------------- 1 | .. Dart VM Overview documentation master file, created by 2 | sphinx-quickstart on Sat Nov 24 23:43:11 2012. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Dart VM Overview's documentation! 7 | ============================================ 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | src/advent201212index 15 | src_en/index 16 | 17 | Indices and tables 18 | ================== 19 | 20 | * :ref:`genindex` 21 | * :ref:`modindex` 22 | * :ref:`search` 23 | 24 | -------------------------------------------------------------------------------- /DartVM/src/advent20131201.rst: -------------------------------------------------------------------------------- 1 | Dart VM Advent Calendar 2013 12/01 2 | ############################################################################### 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | =============================================================================== 11 | 12 | 13 | =============================================================================== 14 | =============================================================================== 15 | =============================================================================== 16 | =============================================================================== 17 | 18 | -------------------------------------------------------------------------------- /DartVM/src/sdk/stream.rst: -------------------------------------------------------------------------------- 1 | Streamの実装 2 | ############################################################################### 3 | 4 | sample 5 | =============================================================================== 6 | 7 | 8 | 9 | =============================================================================== 10 | =============================================================================== 11 | =============================================================================== 12 | =============================================================================== 13 | =============================================================================== 14 | -------------------------------------------------------------------------------- /DartVM/_templates/layout.html: -------------------------------------------------------------------------------- 1 | {% extends "!layout.html" %} 2 | 3 | {% block footer %} 4 | {{ super() }} 5 | 6 | 19 | 20 | {% endblock %} 21 | 22 | -------------------------------------------------------------------------------- /Pyston/src.rst: -------------------------------------------------------------------------------- 1 | 2 | ############################################################################### 3 | ############################################################################### 4 | 5 | ******************************************************************************* 6 | ******************************************************************************* 7 | 8 | =============================================================================== 9 | =============================================================================== 10 | 11 | template :: 12 | ############################################################################### 13 | ******************************************************************************* 14 | =============================================================================== 15 | 16 | -------------------------------------------------------------------------------- /golang/src.rst: -------------------------------------------------------------------------------- 1 | 2 | ############################################################################### 3 | ############################################################################### 4 | 5 | ******************************************************************************* 6 | ******************************************************************************* 7 | 8 | =============================================================================== 9 | =============================================================================== 10 | 11 | template :: 12 | ############################################################################### 13 | ******************************************************************************* 14 | =============================================================================== 15 | 16 | -------------------------------------------------------------------------------- /Pyston/base.rst: -------------------------------------------------------------------------------- 1 | 2 | ############################################################################### 3 | ############################################################################### 4 | 5 | ******************************************************************************* 6 | ******************************************************************************* 7 | 8 | =============================================================================== 9 | =============================================================================== 10 | 11 | template :: 12 | ############################################################################### 13 | ******************************************************************************* 14 | =============================================================================== 15 | 16 | -------------------------------------------------------------------------------- /golang/base.rst: -------------------------------------------------------------------------------- 1 | 2 | ############################################################################### 3 | ############################################################################### 4 | 5 | ******************************************************************************* 6 | ******************************************************************************* 7 | 8 | =============================================================================== 9 | =============================================================================== 10 | 11 | template :: 12 | ############################################################################### 13 | ******************************************************************************* 14 | =============================================================================== 15 | 16 | -------------------------------------------------------------------------------- /DartVM/src/advent2013120x.rst: -------------------------------------------------------------------------------- 1 | Dart VM Advent Calendar 2013 12/01 2 | ############################################################################### 3 | 4 | main 5 | =============================================================================== 6 | 7 | 8 | mark 9 | =============================================================================== 10 | 11 | 12 | sweep 13 | =============================================================================== 14 | =============================================================================== 15 | =============================================================================== 16 | =============================================================================== 17 | =============================================================================== 18 | =============================================================================== 19 | 20 | -------------------------------------------------------------------------------- /art/profile.rst: -------------------------------------------------------------------------------- 1 | Profile 2 | ############################################################################### 3 | 4 | feedbackしてjit compileするわけじゃないんだっけ。 5 | 6 | 7 | ******************************************************************************* 8 | 9 | 10 | 探す際の起点 11 | invoke 12 | 13 | 14 | LIKELY 15 | 16 | record 17 | Record 18 | 19 | profile 20 | Profile 21 | 22 | hierarchy 23 | 24 | ******************************************************************************* 25 | 26 | =============================================================================== 27 | =============================================================================== 28 | 29 | template :: 30 | ############################################################################### 31 | ******************************************************************************* 32 | =============================================================================== 33 | 34 | -------------------------------------------------------------------------------- /OpenJDK/bench/README: -------------------------------------------------------------------------------- 1 | Unsafe周りの調査 2 | ### 3 | 4 | デシリアライズ速度の比較 ByteBuffer vs DirectBuffer vs Unsafe vs C 5 | http://frsyuki.hatenablog.com/entry/2014/03/12/155231 6 | 7 | frsyuki 8 | https://gist.github.com/frsyuki/9502028 9 | 10 | Unsafeがこんな速いのか気になったので調査 11 | 12 | Unsafeの実装 13 | === 14 | 15 | unsafe系は 16 | hotspot/src/share/vm/classfile/vmSymbol.hpp 17 | でvmIntrinsicsに登録されている。 18 | これはログからも確認できる。 19 | 20 | vmIntrinsicsは、各JITコンパイラが個別に命令列に展開する。 21 | C2コンパイラであるoptoの対応箇所は以下 22 | hotspot/src/share/vm/opto/library_call.cpp 23 | case vmIntrinsics::_getLong: return inline_unsafe_access(!is_native_ptr, !is_store, T_LONG, !is_volatile); 24 | 25 | optoの中間表現はidealという名前で、Nodeクラスがグラフ構造でつながっている。 26 | intrinsicsはそのNodeにlibrary_callで置換され、 27 | そのNodeに対応したアセンブラを生成する。 28 | 29 | そのため特定のsymbolへの関数呼び出しに置換されるわけではない。 30 | 31 | inline_unsafe_accessは、その後make_load()関数により、 32 | IdealのNodeであるLoad Nodeに置換される。 33 | 34 | 35 | 注意点 36 | === 37 | 38 | OpenJDK8だとUnsafe + DirectだとSEGVする。Oracle JDKだと大丈夫。 39 | 原因は調査してない。 40 | 41 | -------------------------------------------------------------------------------- /DartVM/src/pub.rst: -------------------------------------------------------------------------------- 1 | export PATH=dart-sdk/bin 2 | 3 | pub installの前後 4 | =============================================================================== 5 | 6 | elise@elise-desktop:~/language/dart$ cd benchmark_harness/ 7 | README.md example lib pubspec.yaml 8 | 9 | elise@elise-desktop:~/language/dart/benchmark_harness$ pub install 10 | Resolving dependencies... 11 | Dependencies installed! 12 | elise@elise-desktop:~/language/dart/benchmark_harness$ ls 13 | README.md example lib packages pubspec.lock pubspec.yaml 14 | 15 | dart Benchmark 16 | =============================================================================== 17 | 18 | elise@elise-desktop:~/language/dart/benchmark_harness/example$ dart DeltaBlue.dart 19 | DeltaBlue(RunTime): 2728.512960436562 us. 20 | 21 | elise@elise-desktop:~/language/dart/benchmark_harness/example$ dart Template.dart 22 | Template(RunTime): 0.5470164764097777 us. 23 | 24 | elise@elise-desktop:~/language/dart/benchmark_harness/example$ dart Richards.dart 25 | Richards(RunTime): 2212.3893805309735 us. 26 | 27 | -------------------------------------------------------------------------------- /golang/async.rst: -------------------------------------------------------------------------------- 1 | async io 2 | ############################################################################### 3 | 4 | 基本的にはgoroutineおこしてそこでやっているのでは。 5 | 6 | ioやsystem callなどを呼び出し前後にgoroutineのcooperativeなschedが走って切り替わる。 7 | 8 | aioのようなOS依存の非同期IOは使用しないようだ。 9 | 10 | =============================================================================== 11 | =============================================================================== 12 | =============================================================================== 13 | 14 | ******************************************************************************* 15 | =============================================================================== 16 | =============================================================================== 17 | 18 | template :: 19 | ############################################################################### 20 | ******************************************************************************* 21 | =============================================================================== 22 | 23 | -------------------------------------------------------------------------------- /art/quick.rst: -------------------------------------------------------------------------------- 1 | quick 2 | ############################################################################### 3 | 4 | ******************************************************************************* 5 | =============================================================================== 6 | =============================================================================== 7 | =============================================================================== 8 | =============================================================================== 9 | ******************************************************************************* 10 | 11 | =============================================================================== 12 | =============================================================================== 13 | 14 | template :: 15 | ############################################################################### 16 | ******************************************************************************* 17 | =============================================================================== 18 | 19 | -------------------------------------------------------------------------------- /art/unit.rst: -------------------------------------------------------------------------------- 1 | Unit 2 | ############################################################################### 3 | 4 | いろいろとまとまった単位をUnitと読んでいるらしい。 5 | 6 | LlvmCompilationUnit 7 | =============================================================================== 8 | 9 | DexCompilationUnit 10 | =============================================================================== 11 | 12 | 13 | ******************************************************************************* 14 | =============================================================================== 15 | =============================================================================== 16 | 17 | 18 | intrinsics 19 | ******************************************************************************* 20 | 21 | cas命令の生成の依存関係を調べてみる。 22 | 23 | CompareExchangeObjectOffset 24 | 25 | CreateAtomicCmpXchgInst 26 | 27 | EmitLockObject 28 | 29 | 30 | dalvikでは、casを直接生成しないんだっけか。 31 | Monitorのlock/unlockでしか使用しない? 32 | 33 | 34 | =============================================================================== 35 | =============================================================================== 36 | 37 | -------------------------------------------------------------------------------- /DartVM/src/devmember.rst: -------------------------------------------------------------------------------- 1 | 2 | floitsch@google.com 3 | ライブラリメインとDartVM間の連携 4 | 5 | DartVMのメイン 6 | 7 | srdjan@google.com 8 | リーダーぽいひと 9 | なんでもできる 10 | 11 | fschneider@google.com 12 | 全範囲メンテ 13 | V8も両方見てる。人間じゃない。 14 | optimizerメイン 15 | 16 | 17 | iposva@google.com 18 | V8の重鎮 19 | 20 | vegorov@google.com 21 | コンパイラの最適化メインの人 22 | 23 | regis@google.com 24 | ARM アセンブラをメインにメンテ 25 | 26 | ager@google.com 27 | V8からの重鎮 28 | 29 | lrn@google.com 30 | V8メイン 31 | 32 | hausner@google.com 33 | 34 | zerny@google.com 35 | 36 | asiva@google.com 37 | cshapiro@google.com 38 | 39 | turnidge@google.com 40 | 41 | kasperl@google.com 42 | 43 | kmillikin@google.com 44 | assemblerとdeoptimize専門の危険人物 45 | パッチ1つの規模が大きい。 46 | 47 | johnmccutchan@google.com 48 | SSEとか専門にやってるひと 49 | 50 | 51 | 少なめ 52 | tball@google.com 53 | sgjesse@google.com 54 | 55 | 56 | V8からの移籍 57 | ager@chromium.org 58 | kasperl@chromium.org 59 | kmillikin@chromium.org 60 | iposva@chromium.org 61 | fschneider@chromium.org 62 | vegorov@chromium.org 63 | lrn@chromium.org 64 | sgjesse@chromium.org 65 | 66 | bak@chromium.org 67 | 68 | 69 | v8 r12826 70 | 73293 line 71 | 72 | dartvm r14000 73 | 15210 line 74 | 75 | kasperとfschneider的は4月 76 | ager的とlrnは7月 77 | 78 | 79 | -------------------------------------------------------------------------------- /DartVM/src/stubs.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | stubs 4 | ====== 5 | 6 | GenerateCallStaticFunctionStub 7 | 8 | CallRuntime(kPatchStaticCallRuntimeEntry 9 | 10 | code_generator.cc 11 | ==== 12 | 13 | PC Descriptors for function 'file:///home/elise/language/dart/work/adven/fibo.dart_::_main' { 14 | pc kind deopt-id tok-ix try-ix 15 | 0xb304818c fn-call 5 42 -1 16 | 0xb304818c deopt-after 5 42 -1 17 | 0xb30481ac other -1 0 -1 18 | 0xb30481b1 return -1 47 -1 19 | 0xb30481c1 other -1 38 -1 20 | 0xb30481c3 patch -1 0 -1 21 | 0xb30481c8 lazy-deopt -1 0 -1 22 | } 23 | Static call target functions { 24 | 0xb304818c: file:///home/elise/language/dart/work/adven/fibo.dart_::_fibo, 0xb5440019 25 | ^ 26 | caller_frame->pc() 27 | } 28 | 29 | PatchStaticCall 30 | 31 | const Function& target_function = Function::Handle( 32 | caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc())); 33 | if (!target_function.HasCode()) { 34 | Compiler::CompileFunction(target_function) 35 | } 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /golang/todo.rst: -------------------------------------------------------------------------------- 1 | Todo 2 | ############################################################################### 3 | 4 | code readingの目標設定 5 | ******************************************************************************* 6 | 7 | golangの大雑把なディレクトリ構造 8 | =============================================================================== 9 | 10 | compilerのざっくりとした流れ 11 | =============================================================================== 12 | 13 | channelみたいのの実現方法 14 | =============================================================================== 15 | 16 | goroutineの実現方法 17 | =============================================================================== 18 | 19 | ioのperformanceがよいらしいけど、どんなかんじか。 20 | =============================================================================== 21 | 22 | 23 | =============================================================================== 24 | 25 | 26 | 27 | =============================================================================== 28 | 29 | ******************************************************************************* 30 | 31 | =============================================================================== 32 | =============================================================================== 33 | 34 | -------------------------------------------------------------------------------- /DartVM/src/future.rst: -------------------------------------------------------------------------------- 1 | Future 2 | ############################################################################### 3 | 4 | Future and completer 5 | ******************************************************************************* 6 | 7 | callcahin :: 8 | 9 | Future.complete 10 | _Future 11 | _asyncComplete(value) 12 | _markPendingCompletion(); 13 | _zone.scheduleMicrotask(() { 14 | _complete(value); 15 | }); 16 | _propagateToListeners() 17 | zone.run() 18 | 19 | 20 | scheduleMicrotask() 21 | 22 | class _ZoneSpecification implements ZoneSpecification { 23 | final scheduleMicrotask 24 | } 25 | 26 | 27 | zone 28 | 29 | rootfork 30 | 31 | forEach 32 | 33 | 34 | zone 35 | =============================================================================== 36 | 37 | ZoneCallback() 38 | ZoneUnaryCallback() 39 | ZoneBinaryCallback() 40 | 41 | 42 | =============================================================================== 43 | =============================================================================== 44 | =============================================================================== 45 | 46 | 47 | =============================================================================== 48 | 49 | -------------------------------------------------------------------------------- /DartVM/src/performance.rst: -------------------------------------------------------------------------------- 1 | performance 2 | ############################################################################### 3 | 4 | StartUp 5 | =============================================================================== 6 | 7 | dart vm 新規にisolateをspawnしてメッセージ受信できるようになるまで10msくらいか。 8 | 10msでhot code replacement / hot loadingできそうだな。 9 | 10 | Coreの読み込みは、 11 | snapshot済みなら、100 micro sec 12 | snapshotなしの場合、100 ms 13 | 1000倍違う。 14 | dartのtime系のオプションで測定すればわかる。 15 | 16 | snapshot済みの場合、file ioとscan済みのメモリの状態をsnapshotでバイナリにする 17 | 普通のcoreで 400kbyte 18 | たぶんmakeの下のヘッダにuint8_t で出力していたはず。 19 | 20 | IO 21 | =============================================================================== 22 | 23 | 1GBのファイルをdartのstream系のapiで全readすると、 24 | ページキャッシュに乗っていれば1.4secくらい、 25 | ページキャッシュをクリアすると20secくらい。2TBのHD。JavaのNIO2あたりと比較してみるか 26 | 27 | GC 28 | =============================================================================== 29 | 30 | newgenのgcが0.6~1 msで、oldgenはcapacityに比例するけど、 31 | oldgenがnewgenと同じ16Mくらいのときで、12-14msくらいか。 32 | 33 | MessagePassing 34 | =============================================================================== 35 | Dart VMのmessage passingのレイテンシは100microsecondから50microsecondくらいか。 36 | JVMとC#と同じ。ほんとにErlang/OTPは5microsecondで終わってんのか、、 37 | 38 | 連続で送信すると、メッセージが詰まる 39 | 40 | MessageBoxは片方向 41 | -------------------------------------------------------------------------------- /golang/gephi.rst: -------------------------------------------------------------------------------- 1 | gephi 2 | ############################################################################### 3 | 4 | ex) :: 5 | 6 | node_header = "nodedef>name VARCHAR, label VARCHAR, width DOUBLE, color VARCHAR\r\n" 7 | edge_header = "edgedef>node1 VARCHAR, node2 VARCHAR, label VARCHAR, weight DOUBLE, color VARCHAR\r\n" 8 | 9 | pritty print sample :: 10 | 11 | if(debug) { 12 | runtime·printf("chansend: chan=%p; elem=", c); 13 | c->elemtype->alg->print(c->elemsize, ep); 14 | runtime·prints("\n"); 15 | } 16 | 17 | 18 | schedgephiオプションを追加してみる。 19 | 20 | runtime·debug.scheddetail) 21 | 22 | ############################################################################### 23 | 24 | ******************************************************************************* 25 | ******************************************************************************* 26 | 27 | =============================================================================== 28 | =============================================================================== 29 | 30 | template :: 31 | ############################################################################### 32 | ******************************************************************************* 33 | =============================================================================== 34 | 35 | -------------------------------------------------------------------------------- /DartVM/src/inlinecache.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | TwoArgsCheckInlineCache 4 | 5 | 6 | void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) { 7 | GenerateUsageCounterIncrement(assembler, EBX); 8 | GenerateNArgsCheckInlineCacheStub(assembler, 2); 9 | } 10 | 11 | counterincrement 12 | usage_ount < 2000 13 | goto is_hot 14 | else incl usage_count_offset 15 | 16 | 17 | GenerateNArgsCheckInlineCacheStub(assembler, 2); 18 | // - If receiver is null -> jump to IC miss. 19 | // - If receiver is Smi -> load Smi class. 20 | // - If receiver is not-Smi -> load receiver's class. 21 | class_id_as_is_smi 22 | 23 | 24 | 25 | label 26 | CallRuntime(inlineCacheMissHandlerXXXArgRuntimeEntry) 27 | 28 | //NosuchMethod or closure 29 | StubCode::InstanceFunctionLoopupLabel() 30 | 31 | found: 32 | addl count_offset 33 | call_tasrget_function: 34 | jmp(EAX) 35 | get_class_id_as_smi: 36 | ret() 37 | not_smi: 38 | LoadClassId 39 | ret() 40 | 41 | 42 | 43 | 最終的に、UpdateICDataTwoArgs 44 | 45 | か、ResolveCompileInstanceCallTarget() 46 | 47 | 48 | 49 | わからないな。。 50 | 51 | Token::kADD 52 | 53 | RawInteger* Integer::ArighmeticOp() ??? 54 | 55 | 56 | addFromInteger ??? 57 | 58 | 59 | intrinsifier_ia32.cc 60 | これ?? Integer_add 61 | 62 | これか? 63 | 64 | 65 | 66 | dart:core__IntegerImplementation@0x36924d72_+function 67 | たぶんこれか。 68 | なぞだ。。 69 | -------------------------------------------------------------------------------- /DartVM/src/out/fibo.fibo.a1.ir: -------------------------------------------------------------------------------- 1 | ==== file:///home/elise/language/dart/work/adven/fibo.dart_::_fibo 2 | B0[graph] { 3 | v0 <- Constant:29(#null) 4 | v1 <- Parameter:30(0) 5 | } 6 | B1[target] 7 | CheckStackOverflow:2() 8 | v2 <- Constant:4(#2) 9 | Branch if RelationalOp:5(<, v1, v2 IC[1: _Smi@0x36924d72, _Smi@0x36924d72 #588]) goto (2, 3) env={ v1, v1, v2 } 10 | B2[target] ^ (<)のreceiverがSmi ^ arg1がSmi 11 | Return:8(v1) 12 | B3[target] 13 | PushArgument:10(v1) 14 | v3 <- Constant:11(#1) 15 | PushArgument:12(v3) 16 | v4 <- InstanceCall:13(-, v1, v3 IC[1: _Smi@0x36924d72, _Smi@0x36924d72 #309]) env={ v1, a0, a1 } 17 | PushArgument:14(v4) ^ (-)のreceiverがSmi ^ arg1がSmi 18 | v5 <- StaticCall:15(fibo v4) env={ v1, a0 } 19 | PushArgument:16(v5) 20 | PushArgument:18(v1) 21 | v6 <- Constant:19(#2) 22 | PushArgument:20(v6) 23 | v7 <- InstanceCall:21(-, v1, v6 IC[1: _Smi@0x36924d72, _Smi@0x36924d72 #278]) env={ v1, a0, a1, a2 } 24 | PushArgument:22(v7) ^ (-)のreceiverがSmi ^ arg1がSmi 25 | v8 <- StaticCall:23(fibo v7) env={ v1, a0, a1 } 26 | PushArgument:24(v8) 27 | v9 <- InstanceCall:25(+, v5, v8 IC[1: _Smi@0x36924d72, _Smi@0x36924d72 #274]) env={ v1, a0, a1 } 28 | Return:26(v9) ^ (+)のreceiverがSmi ^ arg1がSmi 29 | -------------------------------------------------------------------------------- /golang/overview.rst: -------------------------------------------------------------------------------- 1 | Golang 2 | ############################################################################### 3 | 4 | 参考文献 5 | ******************************************************************************* 6 | http://talks.golang.org/2014/go1.3.slide#1 7 | 8 | http://morsmachine.dk/go-scheduler 9 | 10 | https://docs.google.com/document/d/1TTj4T2JO42uD5ID9e89oa0sLKhJYD0Y_kqxDv3I3XMw/edit# 11 | 12 | 13 | arch 14 | =============================================================================== 15 | 16 | x86(386) 17 | 18 | x64(amd64) 19 | 20 | arm 21 | 22 | os 23 | =============================================================================== 24 | 25 | pkg/runtimeの中を参照すると、 26 | 27 | darwin 28 | 29 | dragonfly 30 | 31 | freebsd 32 | 33 | linux 34 | 35 | netbsd 36 | 37 | openbsd 38 | 39 | plan9 40 | 41 | windows 42 | 43 | 44 | ******************************************************************************* 45 | 46 | =============================================================================== 47 | =============================================================================== 48 | 49 | template :: 50 | ############################################################################### 51 | ******************************************************************************* 52 | =============================================================================== 53 | 54 | -------------------------------------------------------------------------------- /DartVM/src/speedup.rst: -------------------------------------------------------------------------------- 1 | 2 | r26773 3 | Collect edge count profiling data and reorder basic blocks. 4 | 5 | DeltaBlue and Richards is speed up 6 | 7 | 8 | 21696 compare optimization 9 | 21692 stackoverflow elimination 10 | 11 | 21235 collect type feedback 12 | 13 | 20373 storebarrier optimize 14 | 15 | 21682 branch optimization 16 | 17 | 18399 redundant load elimination 18 | 19 | 13840 inlining 20 | 21 | 22 | DeltaBlue 23 | =============================================================================== 24 | 25 | r23020 | srdjan@google.com | 2013-05-23 00:20:55 +0900 (木, 23 5月 2013) | 5 lines 26 | Improve constant propagation for Mint and Smi. 27 | R=kmillikin@google.com 28 | Review URL: https://codereview.chromium.org//15507006 29 | 30 | r23018 | srdjan@google.com | 2013-05-22 23:32:18 +0900 (水, 22 5月 2013) | 5 lines 31 | Allow stack location for some instructions (relational and equality comparison). 32 | R=fschneider@google.com 33 | Review URL: https://codereview.chromium.org//15578003 34 | 上記いずれかでDeltaBlueが向上 35 | 36 | Richards 37 | =============================================================================== 38 | 39 | Tracer 40 | =============================================================================== 41 | =============================================================================== 42 | =============================================================================== 43 | -------------------------------------------------------------------------------- /DartVM/src/dart_io.rst: -------------------------------------------------------------------------------- 1 | 2 | src :: 3 | 4 | parentDir.list(recursive: true).where((FileSystemEntity entity) => FileSystemEntity.isFileSync(entity.path)) 5 | .listen((FileSystemEntity entity) { 6 | SHA1 sha1Hash = new SHA1(); 7 | new File(entity.path)..openRead().take(10).listen((List readData) { 8 | sha1Hash.add(readData); 9 | 10 | 11 | sdk/lib/io/file_impl.dart :: 12 | 13 | Stream> openRead([int start, int end]) { 14 | return new _FileStream(path, start, end); 15 | } 16 | 17 | class _FileStream extends Stream> { :: 18 | 19 | // Stream controller. 20 | StreamController> _controller; 21 | 22 | // Information about the underlying file. 23 | String _path; 24 | RandomAccessFile _openedFile; 25 | int _position; 26 | int _end; 27 | final Completer _closeCompleter = new Completer(); 28 | 29 | // Has the stream been paused or unsubscribed? 30 | bool _paused = false; 31 | bool _unsubscribed = false; 32 | 33 | // Is there a read currently in progress? 34 | bool _readInProgress = false; 35 | bool _closed = false; 36 | 37 | // Block read but not yet send because stream is paused. 38 | List _currentBlock; 39 | 40 | 41 | // ここから適当に 42 | new BytesBuilder() 43 | List readSync(int bytes) 44 | external static _read() 45 | 46 | //view 47 | _makeUint8ListView 48 | 49 | readに関してはFileIO 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /golang/syscall.rst: -------------------------------------------------------------------------------- 1 | syscall 2 | ################################################################################ 3 | 4 | cgoの呼び出しはsyscall呼び出しと同様に扱い、GC向けにケアされる 5 | 6 | 7 | system call周りで気づいたこと 8 | ================================================================================ 9 | 10 | goはsystemcallを呼び出す前後において、Syscallでラップして呼び出している。 11 | Syscallはアセンブリで定義されており、アーキテクチャごとにhookを定義している 12 | 13 | amd64 :: 14 | 15 | TEXT ·Syscall(SB),NOSPLIT,$0-56 16 | CALL runtime·entersyscall(SB) 17 | MOVQ a1+8(FP), DI 18 | MOVQ a2+16(FP), SI 19 | MOVQ a3+24(FP), DX 20 | MOVQ $0, R10 21 | MOVQ $0, R8 22 | MOVQ $0, R9 23 | MOVQ trap+0(FP), AX // syscall entry 24 | SYSCALL 25 | CMPQ AX, $0xfffffffffffff001 26 | JLS ok 27 | MOVQ $-1, r1+32(FP) 28 | MOVQ $0, r2+40(FP) 29 | NEGQ AX 30 | MOVQ AX, err+48(FP) 31 | CALL runtime·exitsyscall(SB) 32 | RET 33 | ok: 34 | MOVQ AX, r1+32(FP) 35 | MOVQ DX, r2+40(FP) 36 | MOVQ $0, err+48(FP) 37 | CALL runtime·exitsyscall(SB) 38 | RET 39 | 40 | ポイントは、runtime.entersyscall(SB)と 41 | runtime.exitsyscallを呼び出している点かな? 42 | 43 | entersyscallはcgoにも必ず挿入されるが、 44 | stackguardを挿入したり、pc,spを保存してGC向けにケアする 45 | 46 | 47 | exitsyscallは、mcallでschedulerを呼び出す 48 | 49 | 50 | -------------------------------------------------------------------------------- /DartVM/src/v8_speedup.rst: -------------------------------------------------------------------------------- 1 | V8 SpeedUp 2 | ############################################################################### 3 | 4 | V8で大きく性能向上したコミットを記録 5 | https://www.dartlang.org/performance/ 6 | 7 | DeltaBlue 8 | =============================================================================== 9 | 10 | 19300周辺 11 | 12 | Version 3.24.35 (based on bleeding_edge revision r19214) 13 | Fix inconsistencies wrt whitespaces (issue 3109). 14 | Performance and stability improvements on all platforms. 15 | 16 | Richards 17 | =============================================================================== 18 | 19 | Aggressive Inlining 20 | 21 | Tracer 22 | =============================================================================== 23 | 24 | StoreSinkingの追加 25 | 26 | 27 | FluidMotion 28 | =============================================================================== 29 | 30 | 18411 31 | 32 | 19622でup 33 | r19589 | hpayer@chromium.org | 2014-02-28 01:59:32 +0900 (金, 28 2月 2014) | 15 lines 34 | Merged r19535, r19549, r19586, r19584 into trunk branch. 35 | Fix for a smi stores optimization on x64 with a regression test. 36 | Fix for failing asserts in HBoundsCheck code generation on x64: index register should be zero extended. 37 | Fix putting of prototype transitions. The length is also subject to GC, just like entry. 38 | Handle arguments objects in frame when materializing arguments 39 | 40 | 41 | 19789でdown 42 | Revert "Enable Object.observe by default" 43 | 44 | -------------------------------------------------------------------------------- /golang/goroutine.rst: -------------------------------------------------------------------------------- 1 | goroutine 2 | ############################################################################### 3 | 4 | src/cmd/gc 5 | ******************************************************************************* 6 | 7 | lex.c :: 8 | 9 | go LGO 10 | 11 | go.y :: 12 | 13 | LGO pseudocall 14 | nod(OPROC 15 | 16 | pseudocall() 17 | call-like statemes tha can be preceded by defer and go 18 | OCALL 19 | 20 | //closure 21 | OCLOSURE 22 | OCLOSUREVAR 23 | closurehdr 24 | closurebody 25 | 26 | その他 :: 27 | 28 | gen.c 29 | OPROC 30 | cgen_proc 31 | ODEFER 32 | cgen_proc //new proc running call 33 | cgen_proc 34 | cgen_callmeth //call to non-interface method 35 | cgen_callinter //call to interface method 36 | cgen_call //generate function call 37 | 38 | =============================================================================== 39 | =============================================================================== 40 | 41 | 42 | ******************************************************************************* 43 | 44 | =============================================================================== 45 | =============================================================================== 46 | 47 | template :: 48 | ############################################################################### 49 | ******************************************************************************* 50 | =============================================================================== 51 | 52 | -------------------------------------------------------------------------------- /golang/deadlock.rst: -------------------------------------------------------------------------------- 1 | DeadLockDetector 2 | ############################################################################### 3 | 4 | all goroutines are asleep - deadlock! 5 | 6 | これが出る。 7 | 8 | 9 | src/pkg/runtime 10 | =============================================================================== 11 | 12 | メッセージはproc.cに埋まっていた。 13 | 14 | checkdead() runtime..throw :: 15 | 16 | //これはどういう意味だろう。 17 | // -1 for sysmon 18 | run = runtime..sched.mcount - runtime..sched.nmidle - runtime..sched.nmidlelocked - 1 19 | // Mからnmiddleとnmiddlelockedとsysmonを引いたった。 20 | 21 | // If we are dying because of a signal caught on an already idle thread, 22 | // freezetheworld will cause all running threads to block. 23 | // And runtime will essentially enter into deadlock state, 24 | // except that there is a thread that will call runtime·exit soon. 25 | 26 | if run > 0 continue 27 | if run < 0 panic 28 | なので下記にくるのはrunが0の場合。 29 | 30 | runtime..lock() で全gを止める。中身をiterate 31 | forEach runtime..allglen 32 | gp = runtime..allg[i] 33 | if gp->isbackground continue 34 | if gp state == Gwaiting grunning++ 35 | else if s == Grunnable || s == Grunning || s == Gsyscall 36 | runtimeのcheckdeadに問題ありそう。 37 | runtime..unlock() 38 | 39 | その後強制でdeadlock宣言するのはなんだろうね。。 40 | 41 | 42 | そもそもrun==0の段階でdeadlock 43 | =============================================================================== 44 | 45 | このパスに入った段階でdeadlock確定っぽい。 46 | 47 | 48 | =============================================================================== 49 | =============================================================================== 50 | -------------------------------------------------------------------------------- /DartVM/src/optimizer.rst: -------------------------------------------------------------------------------- 1 | hyperblockform 2 | ############################################################################### 3 | 4 | (1) 5 | optimized comopile時に、通らないパスをpredecessorから除外する。 6 | 7 | (2) 8 | deoptimizeのみの専用命令を作成し、分岐とは別に挿入して1block化する。 9 | 10 | 11 | before 12 | =============================================================================== 13 | instancecallをemitする際に、is_optimizingの場合に、 14 | unoptimized codeをemitする。 15 | compiler->GenerateInstanceCall(deopt_id(), ... 16 | 17 | InstanceCallNoICData 18 | 19 | after 20 | =============================================================================== 21 | まずはいくつくらいno icなケースがあるか確認すべきだろう。 22 | 23 | ApplyICData()の後に、 24 | 25 | def-useの計算前、 26 | constant propagatorの前 27 | 28 | branch simplifier 29 | の中でやる。 30 | 31 | BlockEntryInstrがbbに相当するのかな。 32 | 33 | goto 34 | branch 35 | もしかしてreturnも? 36 | 37 | 38 | gotoの場合、returnに置換するか? 39 | mergeのほうは、 40 | 41 | 42 | return xxx 43 | returnInst->InsertBefore(old_goto) 44 | returnInst->set_next(NULL); 45 | returnInst->UnuseAllInputs(); 46 | block->set_last_instruction(returnInst); 47 | 48 | returninstr token_pos, value 49 | 50 | 51 | 52 | Instruction * instr new ThrowInstr(0); 53 | 54 | predを書き換えて歩く。 55 | 56 | use list 57 | ============================================================================= 58 | 59 | instのInputCount()を捜査 60 | 61 | defn instr->AsDefinition() 62 | defn->input_use_list() 63 | 64 | phiをuse_listにもつ要素(instr, idx)の参照を削除する必要があるな。 65 | 66 | 67 | 68 | =============================================================================== 69 | =============================================================================== 70 | -------------------------------------------------------------------------------- /DartVM/src/message_handler.rst: -------------------------------------------------------------------------------- 1 | MessageHandler 2 | ############################################################################### 3 | 4 | MessageHandlerを起動した際に、 5 | callbackで IsolateMainを起動して、終了したらMessageHandlerを起動する 6 | 7 | whileで回りながら、messageをdequeして 8 | vm/isolate.cc 9 | IsoalteMessageHandler::HandleMessage() 10 | 11 | OOB(out-of-band) Deriver message asap 12 | 13 | void Run() { 14 | handler_->TaskCallback(); 15 | } 16 | 17 | HandleMessage()は 18 | おそらくIsolateMessageHandler::HandleMessage() 19 | 20 | const Object& result = Object::Handle( 21 | DartLibraryCalls::HandleMessage(receive_port, msg)); 22 | 23 | 24 | Isolate 25 | ******************************************************************************* 26 | Isolateが起動すると、 27 | init済みのcallbackを呼び出してeventloopする。 28 | 29 | 30 | isolateの起動 :: 31 | 32 | Isolate::MakeRunnable() 33 | mutex_->Lock(); 34 | Run() 35 | mutex_->Unlock(); 36 | 37 | void Isolate::Run() { 38 | message_handler()->Run(Dart::thread_pool(), 39 | RunIsolate, 40 | ShutdownIsolate, 41 | reinterpret_cast(this)); 42 | } 43 | 44 | 45 | RunIsolate 46 | 47 | //vm/message_handler.cc 48 | 49 | isolateがstartした後に、 50 | HandleMessages 51 | 52 | ******************************************************************************* 53 | 54 | =============================================================================== 55 | =============================================================================== 56 | =============================================================================== 57 | =============================================================================== 58 | 59 | -------------------------------------------------------------------------------- /OpenJDK/print.rst: -------------------------------------------------------------------------------- 1 | PrintCompilation 2 | #### 3 | 4 | option 5 | -XX:+PrintCompilation 6 | 7 | オプションに応じて変数が有効になる。 8 | PrintCompilation 9 | 10 | CompileTask::print_compilation 11 | 12 | 実装 13 | ==== 14 | 15 | hotspot/src/share/vm/print_compilation_impl() :: 16 | 17 | //print timestamp 18 | //print compilation number 19 | 20 | //% is_osr_method 21 | //s is_synchronized 22 | //! has_exception_handler 23 | //b is_blocking 24 | //n is_native 25 | 26 | //comp_level comp_level 27 | 28 | //@ nn //osr_bci 29 | 30 | //(xx bytes) // methodのcode_size() 31 | 32 | //msg 33 | 34 | 35 | comp_level non < comp_level < CompLevel_full_optimization 36 | 37 | is_c2_compile CompLevel_full_optimization 38 | 39 | 40 | enum CompLevel { 41 | CompLevel_any = -1, 42 | CompLevel_all = -1, 43 | CompLevel_none = 0, // Interpreter 44 | CompLevel_simple = 1, // C1 45 | CompLevel_limited_profile = 2, // C1, invocation & backedge counters 46 | CompLevel_full_profile = 3, // C1, invocation & backedge counters + mdo 47 | CompLevel_full_optimization = 4, // C2 or Shark 48 | 49 | mdo <= methoddata 50 | 51 | branches 52 | calls 53 | checkcasts 54 | parameters 55 | arguments 56 | return 57 | 58 | C1UpdateMethodData 59 | 60 | c1_LIRGenerator 61 | 62 | profile_branch 63 | profile_type 64 | profile_parameters 65 | profile_arguments 66 | profile_parameters_at_call 67 | 68 | GraphBuilderのほうでも埋め込む。 69 | profile_call 70 | profile_return_type 71 | profile_invocation 72 | 73 | profile_checkcasts 74 | profile_branches 75 | 76 | 77 | ==== 78 | ==== 79 | ==== 80 | -------------------------------------------------------------------------------- /art/overview.rst: -------------------------------------------------------------------------------- 1 | ART 2 | ############################################################################### 3 | 4 | Android 4.4から追加された、LLVMを内包したJavaVM 5 | compilerとRuntimeとdex系ツールから構成 6 | 7 | 予習 8 | ******************************************************************************* 9 | 10 | http://d.hatena.ne.jp/embedded/20131104/p1 11 | 12 | まとめ。 13 | =============================================================================== 14 | 15 | Android 4.4で試験的に導入されたartはdexコードをターゲット側でAOTコンパイルするもの。 16 | llvm使用。コンパイル結果はファイルとして保存されるので、次回以降はコンパイル済みのコードが使用される。 17 | 18 | oat形式 19 | =============================================================================== 20 | 21 | dexからoat形式に変換する。 22 | elfの書き込みらしいコードもあるので、きっとelfの一種だろう。llvmを使用している。 23 | oatはelf形式の共有オブジェクトを含んでいるようだ 24 | もともとは独自フォーマットだったけど、、今はELF dynamic object 25 | 26 | LLVM 27 | =============================================================================== 28 | 29 | dexからoatへの変換は途中でllvmのbitcodeを経由して、そこで最適化のパスを通るはず。 30 | この最適化でベクタライズもするんだろうな。最新の最適化の技術がそのまま使えるのが強み。 31 | 32 | Runtime 33 | =============================================================================== 34 | 35 | runtimeの中にdexのインタープリタもあるな。 36 | AOTだけじゃなくてJITとしても使えるのかな。 37 | バックグランドでコンパイルして適当なタイミングで差し替えるような。 38 | 39 | libart-compiler はtargetとhostの両方でコンパイルされている。 40 | つまりdexからoatへの変換はhostだけでなくtargetでもできるということ。 41 | 42 | openDexFileNativeというネイティブメソッドがdalvikとartの両方にある。 43 | artの下のものは、その中でdex2oatコマンドをexecしている。 44 | 45 | GC 46 | =============================================================================== 47 | 48 | DalvikVMと同様にコンカレントGCのようです。 49 | 50 | 51 | Author 52 | =============================================================================== 53 | 54 | 拡張子が.ccなのは、V8やDart VM風だけど、AuthorはV8やDart VMと被っていない。 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /golang/json.rst: -------------------------------------------------------------------------------- 1 | golang json 2 | ############################################################################### 3 | 4 | json 5 | ******************************************************************************* 6 | 7 | encoding/json 8 | 9 | v interface{} object型につかうのは、goの基本か。。 10 | 11 | エラーのパターン 12 | src:: 13 | 14 | defer func() { 15 | if r := recover(); r != nil { 16 | if _, ok := r.(runtime.Error); ok { 17 | ... 18 | } 19 | } 20 | } 21 | e.reflectValueがなんちゃら 22 | 23 | valueEncoder(v)(e, v, false) これは関数ポインタぽい 24 | 25 | json 26 | (t reflect.Type) 27 | switch t.Kind() { 28 | case reflect.Bool: 29 | ... 30 | 31 | =============================================================================== 32 | =============================================================================== 33 | =============================================================================== 34 | =============================================================================== 35 | 36 | json rpc 37 | ******************************************************************************* 38 | 39 | net/rpc/jsonrpc 40 | =============================================================================== 41 | 42 | 43 | =============================================================================== 44 | 45 | =============================================================================== 46 | =============================================================================== 47 | 48 | template :: 49 | ############################################################################### 50 | ******************************************************************************* 51 | =============================================================================== 52 | 53 | -------------------------------------------------------------------------------- /erlang/aio.rst: -------------------------------------------------------------------------------- 1 | aioレイヤ 2 | #### 3 | 4 | src_17.0 5 | 6 | aioのレイヤどうなっているのかと。 7 | 主にwindows側をどうしているのか気になる。 8 | 9 | 基本的にはemulator/sys/ose/sys.c 10 | 11 | windows 12 | === 13 | 14 | emulator/sys/win32/sys.c 15 | 16 | struct async_io 17 | 18 | init_async_io 19 | async_read_file 20 | ReadFile(fd, buf, num, aio->bytesTransferred, aio->ov) 21 | async_write_file 22 | 23 | 上記を呼び出すのは、 24 | fd_driver_entry 25 | spawn_driver_entry 26 | struct erl_drv_entry 27 | spawn_start 28 | set_driver_data 29 | 30 | erl_drv_entry vanilla_driver_entryは、unixとwin32双方に定義されている。 31 | 32 | beam/io.c :: 33 | 34 | extern ErlDrvEntry vanilla_driver_entry; 35 | extern ErlDrvEntry spawn_driver_entry; 36 | extern ErlDrvEntry *driver_tab[]; /* table of static drivers, only used during initialization */ 37 | 38 | fd_driver_entry 39 | 40 | driver構造体 41 | 42 | という抽象的な構造体を作って、実装ごとにコントロール可能な 43 | 44 | unix 45 | fdのみ管理、select 46 | fd単位に管理して、pipのfdをdup2によるつなぎ替えを駆使して 47 | 48 | read_inputの中ではread()かな 49 | 50 | ose 51 | aioを使う 52 | 53 | win32 54 | WindowsのReadFile/WriteFileを使う 55 | 56 | erlangは大変勉強になりますね。。 57 | os非依存にfdを管理するdriver構造体を作って、 58 | その実装はose(aio使用),win32,unix(aioなし)の下で適時実装を切り替えると。 59 | OS抽象にthreadへ依存せず非同期IOしてソフトリアルタイム性確保するためにはこれしか解がないのか。。 60 | 61 | 62 | linux 63 | === 64 | 65 | 66 | 中層 67 | === 68 | 69 | READ_AIO 70 | 初期化 71 | aio_read 72 | 73 | WRITE_AIO 74 | 初期化 75 | aio_write 76 | 77 | aio_dispatch(sig) 78 | 79 | 80 | 81 | 具体的には 82 | 83 | 84 | beam/io.c 85 | 86 | extern ErlDrvEntry fd_driver_entry; 87 | extern ErlDrvEntry vanilla_driver_entry; 88 | extern ErlDrvEntry spawn_driver_entry; 89 | 90 | 91 | 初期はこういうのが続く。 92 | init_driver(&vanilla_driver, &vanilla_driver_entry, NULL); 93 | 94 | call_driver_control()を使って呼び出される。 95 | drv_ptr->control() 96 | (ErlDrvData)prt->drv_data 97 | 98 | 99 | -------------------------------------------------------------------------------- /DartVM/src/external.rst: -------------------------------------------------------------------------------- 1 | 2 | sdk/lib/scalarlist 3 | 4 | byte_arrays.dart 5 | external factory Float64List(int lenght); 6 | external factory Float64List.view(ByteArray array, [int start, int length]); 7 | 8 | 9 | runtime/lib/byte_array.dart 10 | 11 | patch class Float64List { 12 | factory Float64List(int length) { 13 | new _Float64List(length); 14 | } 15 | } 16 | static _Float64Array _new(int length) native "Float64Array_new"; 17 | 18 | 19 | externalは、raw objectに、実配列を含んでいない。 20 | raw objectには、sizeとreferenceのみ格納している。 21 | 22 | external arrayの場合、length, raw_array を格納しているため、instance sizeに、lengthを引数に与えて計算する必要我ある。 23 | 24 | 25 | 26 | +intptr_t RawUint8ClampedArray::VisitUint8ClampedArrayPointers( 27 | + RawUint8ClampedArray *raw_obj, ObjectPointerVisitor* visitor) { 28 | + // Make sure that we got here with the tagged pointer as this. 29 | + ASSERT(raw_obj->IsHeapObject()); 30 | + intptr_t length = Smi::Value(raw_obj->ptr()->length_); 31 | + visitor->VisitPointers(raw_obj->from(), raw_obj->to()); 32 | + return Uint8ClampedArray::InstanceSize(length); 33 | +} 34 | 35 | +intptr_t RawExternalUint8ClampedArray::VisitExternalUint8ClampedArrayPointers( 36 | + RawExternalUint8ClampedArray* raw_obj, ObjectPointerVisitor* visitor) { 37 | + // Make sure that we got here with the tagged pointer as this. 38 | + ASSERT(raw_obj->IsHeapObject()); 39 | + visitor->VisitPointers(raw_obj->from(), raw_obj->to()); 40 | + return ExternalUint8ClampedArray::InstanceSize(); 41 | +} 42 | 43 | Uint8ClampedArray 44 | は、Ecmaのtyped array specification 45 | 46 | 47 | どこで使うのか。 48 | =============================================================================== 49 | newTransferableをつけると、externalを使って領域確保する。 50 | 51 | GCの対象外になるため、transferableは譲渡可能の意味らしい。 52 | 53 | GCの対象外になるため、ashmemみたいな使い方なのか。プロセス間通信に使うのか?isolateなどで? 54 | 55 | 56 | -------------------------------------------------------------------------------- /golang/resource.rst: -------------------------------------------------------------------------------- 1 | resource 2 | ############################################################################### 3 | 4 | OS抽象化層 5 | =============================================================================== 6 | 7 | bsdthread_create 8 | 9 | これかな? 10 | 11 | 12 | PがThreadに対応するはず 13 | =============================================================================== 14 | 15 | M 16 | P 17 | G 18 | 19 | thread 20 | ******************************************************************************* 21 | 22 | runtime..asmcgocall 23 | 24 | 25 | threadの生成 26 | =============================================================================== 27 | 28 | proc.c::newm(fn, P) 29 | if() runtime..asmcgocall() 30 | runtime..newosproc() 31 | 32 | linuxの場合 33 | runtime..newosproc() 34 | ret = runtime..clone() 35 | 36 | Windowsの場合 37 | runtime..newosproc() 38 | thandle = runtime..stdcall(rntime..CreateThread, 39 |   40 | 41 | 42 | runtime..newosproc(M, stk) 43 | sys_darwin_amd64.s 44 | void bsdthread_create(stk, M, G, fn) 45 | 46 | 47 | =============================================================================== 48 | =============================================================================== 49 | =============================================================================== 50 | 51 | 52 | 53 | 54 | 55 | ******************************************************************************* 56 | 57 | =============================================================================== 58 | =============================================================================== 59 | 60 | template :: 61 | ############################################################################### 62 | ******************************************************************************* 63 | =============================================================================== 64 | 65 | -------------------------------------------------------------------------------- /DartVM/src/out/fibo.clang32.asm: -------------------------------------------------------------------------------- 1 | // 2 | //clang3.2 -O3 3 | // 4 | 5 | int fibo(int n) { 6 | if (n < 2) { 7 | //then 8 | return n; 9 | } else { 10 | //else 11 | return fibo(n-1) + fibo(n-2); 12 | } 13 | } 14 | 15 | //objdump -d -M intel 16 | 080483f0 : 17 | 80483f0: 57 push edi 18 | 80483f1: 56 push esi 19 | 80483f2: 50 push eax 20 | 80483f3: 8b 74 24 10 mov esi,DWORD PTR [esp+0x10] // esi <-- n 21 | 80483f7: 83 fe 02 cmp esi,0x2 // if (n < 2) 22 | 80483fa: 7d 04 jge 8048400 // goto then 23 | // else 24 | 80483fc: 89 f0 mov eax,esi // eax <-- esi 25 | 80483fe: eb 1a jmp 804841a // goto return 26 | // then 27 | 8048400: 8d 46 ff lea eax,[esi-0x1] // eax <-- n - 1 28 | 8048403: 89 04 24 mov DWORD PTR [esp],eax // push (n-1) 29 | 8048406: e8 e5 ff ff ff call 80483f0 // call fibo1 30 | 804840b: 89 c7 mov edi,eax // edi <-- ret1 31 | 804840d: 83 c6 fe add esi,0xfffffffe // esi <-- n - 2 32 | 8048410: 89 34 24 mov DWORD PTR [esp],esi // push (n-2) 33 | 8048413: e8 d8 ff ff ff call 80483f0 // call fibo2 34 | 8048418: 01 f8 add eax,edi // eax <-- ret2 + ret1 35 | // return 36 | 804841a: 83 c4 04 add esp,0x4 37 | 804841d: 5e pop esi 38 | 804841e: 5f pop edi 39 | 804841f: c3 ret // return eax 40 | 41 | -------------------------------------------------------------------------------- /DartVM/src/out/fibo.fibo.ir: -------------------------------------------------------------------------------- 1 | 2 | ==== file:///home/elise/language/dart/work/adven/fibo.dart_::_fibo 3 | B0[graph] 4 | B1[target] 5 | CheckStackOverflow:2() 6 | t0 <- LoadLocal:3(n lvl:0) //変数nをLoad(引数という概念はここではない) 7 | t1 <- Constant:4(#2) //定数2を生成 8 | Branch if RelationalOp:5(<, t0, t1) goto (2, 3) //(t0 < t1)だったら、B2へjump、もしくはB3へjump 9 | B2[target] 10 | t0 <- LoadLocal:7(n lvl:0) //定数nをLoad 11 | Return:8(t0) //Return 12 | B3[target] 13 | t0 <- LoadLocal:9(n lvl:0) //変数nをLoad 14 | PushArgument:10(t0) //nを引数にpush 15 | t0 <- Constant:11(#1) //定数1を生成 16 | PushArgument:12(t0) //#1を引数にpush 17 | t0 <- InstanceCall:13(-, t0, t0) //InstanceCall (-)(n, #1)みたいなメソッドコール 18 | PushArgument:14(t0) //返値をpush [`n-1`] 19 | t0 <- StaticCall:15(fibo t0) //fibo(n-1)に相当 20 | PushArgument:16(t0) //返値をpush [`fibo(n-1)`] 21 | t0 <- LoadLocal:17(n lvl:0) //変数nをLoad 22 | PushArgument:18(t0) //nをpush 23 | t0 <- Constant:19(#2) //定数2を生成 24 | PushArgument:20(t0) //#2をpush 25 | t0 <- InstanceCall:21(-, t0, t0) //InstanceCall (-)(n, 2)みたいなメソッドコール 26 | PushArgument:22(t0) //返値をpush [`fibo(n-1)`, `n-2`] 27 | t0 <- StaticCall:23(fibo t0) //fibo(n-2)に相当 28 | PushArgument:24(t0) //返値をpush [`fibo(n-1)`, `fibo(n-2)`] 29 | t0 <- InstanceCall:25(+, t0, t0) //InstanceCall (+)(`fibo(n-1)`, `fibo(n-2)`) 30 | Return:26(t0) //返値をreturn 31 | 32 | -------------------------------------------------------------------------------- /erlang/erlang_overview.rst: -------------------------------------------------------------------------------- 1 | Erlang Overview 2 | ############################################################################### 3 | 4 | Erlang 言語の特徴 5 | 6 | * 関数型言語 7 | * 先行評価 8 | * 変数への代入は1回限り 9 | * 動的型付け 10 | 11 | 関数型言語っていうのは、関数がファーストクラスという意味なのだと思う。 12 | 13 | 関数はメッセージにもできるし、spawnの対象、asyncの対象、メッセージにシリアライズできる。 14 | 15 | ホットスワップ、ホットローディング、障害時の復帰、Migrationの対象にできる。 16 | 17 | 変数への代入が一回限りという制約は、VMを実装する上でどのようなメリットがあるのか。 18 | GCの設計で恩恵があるとかどうとか。 19 | 20 | 21 | 特徴(wikipediaから抜粋) 22 | =============================================================================== 23 | 24 | * 分散化された環境 (プロセス間、コア間、ノード間) 25 | * 障害に耐性をもつ (フォルトトレラント) 26 | * ある程度のリアルタイム性を備える 27 | * 無停止で稼働する (低レイテンシかつ無停止のGC) 28 | * ホットスワップが可能であり、稼働中のシステムを停止すること無くErlangのプログラムを変更することができる。 29 | 30 | * インタプリタ + HiPE 31 | エリクソンによるErlangの実装は基本的にはインタプリタであるが、 32 | HiPEというコンパイラも同社の実装に含まれている。 33 | 34 | ただしHiPEはErlangが動作する全てのプラットフォームで使えるわけではない。 35 | 36 | * 軽量なプロセス 37 | OSのプロセスではなく、独自のprocess 38 | 39 | プロセス同士はメモリを共有しないで、完全に独立している。 40 | 41 | プロセスの交代は非常に高速である。 42 | 43 | プロセス同士の連絡は非常に高速に行なわれる。 44 | 45 | * プロセス間通信 46 | 非同期のメッセージ転送システム 47 | 48 | 「メールボックス」 メールボックスには他のプロセスから受信したメッセージが格納される。 49 | 50 | メールボックスに格納されたメッセージがメールボックスを所有するプロセスによって処理される。 51 | 52 | そのときErlangのプロセスはメッセージを得るために receive という基本操作を行う。 53 | 54 | メッセージが処理されると、メッセージはメールボックスキューから除去され、 55 | 56 | プロセスは復帰して続きの処理を行う。 57 | 58 | つまり1プロセスに付き1メールボックス、非同期のメッセージ転送システムは、プロセス間で行う。 59 | 60 | Erlangの構成要素は何であれメッセージとして使うことができる。 61 | 62 | Erlangの基本要素である整数 (integer) 、浮動小数点数 (float) 、 63 | 64 | 文字 (character) 、atomも、またタプル、リスト、さらには関数さえも、メッセージとして扱うことができる。 65 | 66 | 67 | Erlangでは異なるノード (コンピュータ) に分散した複数のプロセスを互いに連携させて 68 | 動作させるためのサポートも組み込みで備えている (分散処理) 。 69 | 70 | プロセスは遠隔のノードに生成することができ、遠隔ノード上のプロセスとのプロセス間通信は透過的である。 71 | 72 | すなわち、遠隔ノード上のプロセスとのプロセス間通信は、 73 | 同じノード上のプロセスとのプロセス間通信と全く同じように行われる。 74 | 75 | Erlangでの並行処理では、エラー処理の基本的な方法をサポートしている。 76 | 77 | あるプロセスが異常をきたすと、プロセスは手際良く終了し、 78 | そのプロセスを制御しているプロセス 79 | (何らかのアクションをとることができるプロセス) にメッセージを送信する。 80 | 81 | このエラー処理の方法により、ソースコードの保守性を高め複雑性を低減することができる。 82 | -------------------------------------------------------------------------------- /Ethereum/overview.rst: -------------------------------------------------------------------------------- 1 | overview 2 | ############### 3 | 4 | ここ一読 5 | https://y-nakajo.hatenablog.com/entry/2018/05/11/171446 6 | 7 | http://coffeetimes.hatenadiary.jp/entry/2017/11/07/082426 8 | 9 | dir/tree 10 | ############### 11 | 12 | go-ethereum 13 | https://github.com/ethereum/go-ethereum 14 | 15 | accounts/ 16 | abi 17 | keystore 18 | usbwallet 19 | 20 | bmt/ Binary Merkle Tree Hash 21 | cmd/ 22 | common/ 23 | bitutil/ 24 | compiler/ solidity 25 | fdlimit/ //os依存 26 | hexutil 27 | math 28 | mclock 29 | number 30 | 31 | consensus/ 32 | clique/ proof-of-authority 33 | ethash/ 34 | misc 35 | console/ 36 | containers/ docker 37 | contracts/ 38 | chequebook/ 39 | ens/ naming service -> address変換 40 | core/ 41 | ams/ 42 | bloombits/ 43 | rawdb/ 44 | state/ 45 | types/ 46 | vm/ 47 | runtime/ 48 | crypto/ 49 | bn256/ porting 50 | cloudflare/ 51 | google/ 52 | ecies/ elliptic curve 53 | randentropy/ 54 | secp256k1/ 55 | sha3/ 56 | dashboard/ 57 | eth/ 58 | downloader/ 59 | fetcher/ 60 | filters/ 61 | gasprice/ 62 | tracers/ 63 | ethclient/ 64 | ethdb/ leveldb 65 | ethstats/ 66 | event/ 67 | filter/ 68 | internal/ 69 | debug/ 70 | ethapi/ 71 | guide/ 72 | jsre/ 73 | web3ext/ 74 | les/ lightEthereum backend 75 | light /lightChain 76 | log/ 77 | term/ 78 | metrics/ 79 | exp/ 80 | influxdb/ 81 | librato/ 82 | miner/ 83 | mobile/ 84 | node/ 85 | p2p/ 86 | discover/ 87 | discv5/ 88 | enr/ 89 | nat/ 90 | netutil/ 91 | protocols/ 92 | params/ 93 | rlp/ Recursive Length Prefix 94 | rpc/ 95 | signer/ 96 | core/ 97 | rules/ 98 | storage/ 99 | swarm/ 100 | api/ 101 | http/ 102 | fuse/ 103 | metrics/ 104 | network/ 105 | kademlia/ 106 | services/ 107 | swap/ 108 | storage/ 109 | trie/ merkle patricia tries. 110 | vendor/ 111 | whisper/ 112 | mailserver/ 113 | shhclient/ 114 | whisperv5 115 | whisperv6/ 116 | 117 | 118 | 主要な操作はinterfaces.goから追うか 119 | -------------------------------------------------------------------------------- /golang/cc.rst: -------------------------------------------------------------------------------- 1 | callchain 2 | ############################################################################### 3 | 4 | goのmainから辿る。 5 | 6 | go main 7 | ******************************************************************************* 8 | 9 | main :: 10 | 11 | asm_amd64.s::_rt0_go 12 | runtime..args 13 | runtime..osinit 14 | runtime..hashinit 15 | runtime..schedinit 16 | runtime..symtabinit 17 | runtime..mallocinit 18 | mcommoninit(m) 19 | 20 | pushq runtime..main..f 21 | runtime..newproc //create a new goroutine to start program 22 | runtime/proc.c::runtime..shced 23 | 24 | runtime..mstart //start this M ここで-vの出力が走る 25 | runtime..mstart() 26 | runtime..gosave() 27 | runtime..asminit() 28 | runtime..minit() 29 | runtime..initsig() 30 | m->mstartfn() 31 | schedule() 32 | stopm() 33 | 34 | runtime..starttheworld(void) 35 | 36 | proc bootstrap :: 37 | 38 | // The bootstrap sequence is: 39 | // 40 | // call osinit 41 | // call schedinit 42 | // make & queue new G 43 | // call runtime·mstart 44 | // 45 | // The new G calls runtime·main. 46 | 47 | 48 | runtime 49 | =============================================================================== 50 | 51 | starttheworld 52 | stoptheworld 53 | freezetheworld 54 | 55 | 56 | stoptheworld 57 | M 58 | P 59 | G 60 | 61 | 62 | 63 | stopm 64 | =============================================================================== 65 | 66 | callback :: 67 | 68 | execute(gp) 69 | resetspinning() 70 | 71 | 72 | 73 | 74 | =============================================================================== 75 | =============================================================================== 76 | 77 | 78 | ******************************************************************************* 79 | 80 | native thread 81 | =============================================================================== 82 | 83 | 84 | =============================================================================== 85 | -------------------------------------------------------------------------------- /DartVM/src/base.rst: -------------------------------------------------------------------------------- 1 | 部 2 | ############################################################################### 3 | 4 | 章 5 | ******************************************************************************* 6 | 7 | セクション 8 | =============================================================================== 9 | 10 | サブセクション 11 | ------------------------------------------------------------------------------- 12 | 13 | =============================================================================== 14 | =============================================================================== 15 | =============================================================================== 16 | ------------------------------------------------------------------------------- 17 | ------------------------------------------------------------------------------- 18 | ------------------------------------------------------------------------------- 19 | 20 | 21 | ------------------------------------------------------------------------------- 22 | ------------------------------------------------------------------------------- 23 | ------------------------------------------------------------------------------- 24 | ------------------------------------------------------------------------------- 25 | 26 | ------------------------------------------------------------------------------- 27 | 28 | ------------------------------------------------------------------------------- 29 | 30 | 31 | 32 | 33 | =============================================================================== 34 | 35 | 36 | ------------------------------------------------------------------------------- 37 | ------------------------------------------------------------------------------- 38 | ------------------------------------------------------------------------------- 39 | 40 | 41 | 42 | 43 | .. 44 | .. image:: xxx.png 45 | .. 46 | .. literalinclude:: xxx.js 47 | .. 48 | .. graphviz:: 49 | .. 50 | .. 51 | .. xxx :: 52 | .. 53 | .. xxx 54 | .. 55 | .. code-block:: python 56 | .. :linenos: 57 | .. 58 | .. literalinclude:: src/test.py 59 | .. 60 | .. :language: python 61 | .. :linenos: 62 | .. 63 | 64 | -------------------------------------------------------------------------------- /OpenJDK/numa.rst: -------------------------------------------------------------------------------- 1 | NUMA関連のオプション 2 | ############################################################################### 3 | 4 | UseNUMA 5 | UseNUMAInterleaving 6 | NUMAInterleaveGranularity 2M 7 | 8 | オプションはruntime/globals 9 | 10 | NUMA系は、 11 | gc/shareのTLAB関連にはNUMAのオプション関係あり。 12 | もしくはParallelGCに影響ある。 13 | G1GCには直接関係ない。 14 | 15 | UseTLAB thread-local object allocation 16 | =============================================================================== 17 | 18 | allocate 19 | memory/threadLocalAllocBuffer::allocate 20 | invariants() あまり関係ない 21 | 22 | jdk 1.7 を見た感じ XX:useNUMAというのは要するに、 23 | あるスレッドからしか使われないメモリとグローバルヒープを分ける。 24 | ローカルヒープからグローバルヒープに遷移するときに mbind(INTERELEAVE) するという戦略のようだ。 25 | 26 | 27 | LinuxのAUTONUMAとのアンマッチ 28 | =============================================================================== 29 | 大きなヒープをNUMA無視して扱っていると関係なくなる。 30 | 31 | numaで確保したメモリがlarge pageにfitするように調整するのみ。 32 | numa向けにadaptiveなpage sizeの調整。region 33 | 34 | linux/os_linux.cpp 35 | id = os::numa_get_group_id() 36 | thread->set_lgrp_id(id) 37 | 38 | UseNUMAInterleaving 39 | numa_make_global(addr,size) 40 | 41 | Linux::numa_interleave_memory 42 | Linux::numa_tonode_memory 43 | 44 | gc 45 | bias_region() 46 | os::numa_make_local() 47 | numa_tonode_memory() 48 | 49 | 50 | MutableNUMASpace 51 | parallelScavengeのeden_spaceのみ 52 | 53 | GCから呼ばれるNUMA関連のsystem call 54 | =============================================================================== 55 | 56 | static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; } 57 | static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; } 58 | static void set_numa_max_node(numa_max_node_func_t func) { _numa_max_node = func; } 59 | static void set_numa_available(numa_available_func_t func) { _numa_available = func; } 60 | static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; } 61 | static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = f 62 | static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; } 63 | static int sched_getcpu_syscall(void); 64 | 65 | 66 | -------------------------------------------------------------------------------- /art/todo.rst: -------------------------------------------------------------------------------- 1 | TODO 2 | ############################################################################### 3 | 4 | 読み進める前に、ARTの疑問点と予想の洗い出し 5 | 6 | 7 | 疑問点 8 | ******************************************************************************* 9 | 10 | LLVM 11 | =============================================================================== 12 | llvm-irに変換する際に何かやる? 13 | 14 | >> dex->llvmあたりを読む必要あり。 15 | 16 | llvm-irに変換する際の、object headerはどうするのか、gcやruntimeとの連携を事前埋め込み? 17 | 18 | 上記は全部独自のintrinsicsを定義して埋め込み? 19 | 20 | >> intrinsicsとShadowFrameで解決するっぽい。そもそもDalvikってObjectHeaderどうなってるの。 21 | 22 | >> 事前に大量のintrinsicsを埋め込んだ後に、GBCExpanderパスでput/get系はexpand 23 | 24 | llvmの制御はどうやっている? 25 | 26 | >> llvmとの連携は、全部intrinsicのみ あとはMDで制御。TBAAとか。 27 | 28 | Runtime 29 | =============================================================================== 30 | 31 | Runtimeの最小構成は? 32 | 33 | 各種連携はentry pointらしい。safe pointみたいなものか。 34 | 35 | >> intrinsicsに対応した、呼び出し先の実装らしい。いつでも呼べるように考慮してるのかも。 36 | 37 | Reflectionからmirrorに変わっているらしいが。 38 | 39 | >> Reflectionっていう用語は完全にJava.langのみ。artのruntimeは全部mirrorに統一。 40 | 41 | intrinsicの全定義がruntimeにあるか? 42 | 43 | >> ない。GBCExpanderで大部分解決している。ある程度はentrypointで定義されていて、 44 | compilerが生成したコードから、自由にruntimeを呼べるようになっている。 45 | 46 | deoptimize 47 | 48 | >> やるらしい。entrypointの中で、quickとportableの双方で定義されていた。まだ動いてないはず。 49 | どこかにclassloader/mirrorからのトリガーがあるはずだが。 50 | 51 | quick portableの連携 52 | 53 | >> まだ何もない。 54 | 55 | SeaIr 56 | =============================================================================== 57 | 58 | sea_irの使い道は、なぞ 59 | 60 | 61 | commit log 62 | =============================================================================== 63 | 64 | 65 | commit 818f2107e6d2d9e80faac8ae8c92faffa83cbd11 66 | Author: Nicolas Geoffray 67 | Date: Tue Feb 18 16:43:35 2014 +0000 68 | 69 | Re-apply: Initial check-in of an optimizing compiler. 70 | 71 | The classes and the names are very much inspired by V8/Dart. 72 | It currently only supports the RETURN_VOID dex instruction, 73 | and there is a pretty printer to check if the building of the 74 | graph is correct. 75 | 76 | Change-Id: I28e125dfee86ae6ec9b3fec6aa1859523b92a893 77 | 78 | -------------------------------------------------------------------------------- /Pyston/overview.rst: -------------------------------------------------------------------------------- 1 | Pyston 2 | ############################################################################### 3 | 4 | blog要約 5 | ******************************************************************************* 6 | https://tech.dropbox.com/2014/04/introducing-pyston-an-upcoming-jit-based-python-implementation/ 7 | 8 | Dropbox 9 | 10 | C++で開発 11 | 12 | 既にpythonのJITを使用した実装はいろいろある。 13 | 14 | PyPy tracing JIT 15 | Jython and IronPythonは、その下のVMがJITコンパイルをサポートしている。 16 | 17 | method-at-a-time JITとして実装したい。 18 | 19 | conservative gabarge collector 20 | 21 | using LLVM 22 | 23 | type speculation 24 | 25 | inline caches 26 | 27 | README 28 | =============================================================================== 29 | 30 | python 2.7 and x86_64 31 | 32 | 33 | 4tiers 34 | 1.LLVM-IR itnerpreter 35 | 2.Baseline LLVM compilation type recording 36 | 3.Improved LLVM compilation 37 | 4.Full LLVM optimization, uses type feedback 38 | 39 | 今はlow tierへ戻れない 40 | 41 | いろんなテクニック 42 | =============================================================================== 43 | Inlining 44 | 45 | Object Representation, boxed model 46 | int flaot bool 47 | 48 | Inline caches 49 | 50 | Hidden classes 51 | 52 | Type feedback 53 | 54 | Garbage collection 55 | 56 | Aspiration: Extension modules 57 | 58 | Aspiration: Thread-level Parallelism 59 | 60 | 61 | 62 | =============================================================================== 63 | =============================================================================== 64 | =============================================================================== 65 | ******************************************************************************* 66 | ******************************************************************************* 67 | 68 | =============================================================================== 69 | =============================================================================== 70 | 71 | template :: 72 | ############################################################################### 73 | ******************************************************************************* 74 | =============================================================================== 75 | 76 | -------------------------------------------------------------------------------- /DartVM/src/deopt3.rst: -------------------------------------------------------------------------------- 1 | Deoptの準備 2 | ############################################################################### 3 | 4 | =============================================================================== 5 | 6 | Deopt stub for :: 7 | 8 | ;; Deopt stub for id 14 9 | 0xb3148916 e8254c1f02 call 0xb533d540 [stub: Deoptimize] 10 | 0xb314891b cc 11 | 12 | void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, 13 | intptr_t stub_ix) { 14 | // Calls do not need stubs, they share a deoptimization trampoline. 15 | ASSERT(reason() != kDeoptAtCall); 16 | Assembler* assem = compiler->assembler(); 17 | #define __ assem-> 18 | __ Comment("Deopt stub for id %"Pd"", deopt_id()); 19 | __ Bind(entry_label()); 20 | if (FLAG_trap_on_deoptimization) __ int3(); 21 | 22 | ASSERT(deopt_env() != NULL); 23 | 24 | __ call(&StubCode::DeoptimizeLabel()); 25 | set_pc_offset(assem->CodeSize()); 26 | __ int3(); 27 | #undef __ 28 | } 29 | 30 | 31 | DeoptInfo 32 | =============================================================================== 33 | 34 | 重要な要素 35 | deopt_id 36 | DeoptReasonId 37 | Environment 38 | 39 | class CompilerDeoptInfo 40 | 上記をwrapして、pcを保持するだけ。labelが付いたのかな。 41 | 42 | 43 | Environment 44 | =============================================================================== 45 | もしかして、Environmentがコア技術だったりするのかな。 46 | 47 | InstructionにEnvをget set removeできる。 48 | 49 | 自動メンテしてるのか? 50 | 51 | DeepCopy() 52 | Location 53 | values_ 54 | ValueAtUseIndex 55 | From 56 | 57 | 58 | 参照しているポイント 59 | =============================================================================== 60 | flow_graph 61 | flow_graph_compiler 62 | flow_graph_optimizer 63 | 64 | まとめ 65 | =============================================================================== 66 | Dart VMのDeoptimizationのキモは、Environmentなのかな。Environment自体は、一般のコンパイラのデバッグ情報に相当する部分で、builderおよびoptimizerの各種最適化で使用される、IRへ副作用を伴う操作が自動メンテするのか。 67 | Environmentを正しくメンテできる範囲においてIRをoptimizeしてよいし、Environmentが正しければdeoptimizeされるはずってことか。。Environmentを壊すような、命令の順序入れ替えや、アグレッシブなLOOP最適化はNGってことなのかな 68 | 69 | 70 | =============================================================================== 71 | -------------------------------------------------------------------------------- /DartVM/src/out/fibo.main.asm: -------------------------------------------------------------------------------- 1 | code for function 'file:///home/elise/language/dart/work/adven/fibo.dart_::_main' { 2 | //prolog 3 | CheckStackOverflow:2() 4 | 0xb2f88168 55 push ebp 5 | 0xb2f88169 89e5 mov ebp,esp 6 | 0xb2f8816b e800000000 call 0xb2f88170 7 | 0xb2f88170 3b256cfa7f08 cmp esp,[0x87ffa6c] 8 | 0xb2f88176 0f8636000000 jna 0xb2f881b2 9 | 10 | //main body 11 | t0 <- Constant:3(#40) 12 | PushArgument:4(t0) 13 | StaticCall:5(fibo t0) 14 | 0xb2f8817c b850000000 mov eax,0x50 <-- fiboの引数40 15 | 0xb2f88181 50 push eax 16 | 0xb2f88182 bab16b03b3 mov edx,0xb3036bb1 Array[1, 1, null] 17 | 0xb2f88187 e87c823702 call 0xb5300408 [stub: CallStaticFunction] <-- Stub越しにfibo呼び出し 18 | 0xb2f8818c 83c404 add esp,0x4 19 | 20 | //epilog 21 | t0 <- Constant:6(#null) 22 | 0xb2f8818f b8190038b5 mov eax,0xb5380019 <-- 'null' 23 | 0xb2f88194 50 push eax 24 | Return:7(t0) 25 | 0xb2f88195 58 pop eax 26 | 0xb2f88196 ba690421b3 mov edx,0xb3210469 'Function 'main': static.' のテーブル取得。 27 | 0xb2f8819b ff422b inc [edx+0x2b] <-- 'inc usage_counter' 28 | 0xb2f8819e 817a2bd0070000 cmp [edx+0x2b],0x7d0 <-- check hotcode 0x7d0==2000 29 | 0xb2f881a5 7c05 jl 0xb2f881ac 30 | 0xb2f881a7 e8fc86ffff call 0xb2f808a8 [stub: OptimizeFunction] <-- call JITCompiler!!! 31 | 0xb2f881ac 89ec mov esp,ebp 32 | 0xb2f881ae 5d pop ebp 33 | 0xb2f881af c3 ret 34 | 0xb2f881b0 90 nop 35 | 0xb2f881b1 cc int3 36 | 37 | //runtime 38 | 0xb2f881b2 b9f0c20a08 mov ecx,0x80ac2f0 39 | 0xb2f881b7 ba00000000 mov edx,0 40 | 0xb2f881bc e8677e3702 call 0xb5300028 [stub: CallToRuntime] 41 | 0xb2f881c1 ebb9 jmp 0xb2f8817c 42 | 0xb2f881c3 e960833702 jmp 0xb5300528 [stub: FixCallersTarget] 43 | 0xb2f881c8 e93b843702 jmp 0xb5300608 [stub: DeoptimizeLazy] 44 | } 45 | 46 | -------------------------------------------------------------------------------- /DartVM/src/stream.rst: -------------------------------------------------------------------------------- 1 | stream 2 | ############################################################################### 3 | 4 | sdk/lib/async/stream 5 | ******************************************************************************* 6 | 7 | isolate_patch.dart 8 | 9 | StreamController 10 | 11 | 12 | 13 | ReceivePortImpl 14 | =============================================================================== 15 | 16 | extends Stream 17 | 18 | StreamSubscription listen(void onData 19 | _controller.stream.listen() 20 | 21 | final RawReceivePort _rawPort 22 | StreamController _controller; 23 | 24 | StreamController 25 | =============================================================================== 26 | 27 | Stream get stream; 28 | 29 | 30 | listen 31 | StreamSusscription 32 | .onData 33 | _onListen(subscription) 34 | 35 | 36 | 37 | _onListenHandler = Zone.current.registerUnaryCallback(onListenHandler) 38 | 39 | 40 | 41 | handle 42 | =============================================================================== 43 | 44 | _handleMessage 45 | schedule_microtask.dart::_asyncRunCallback 46 | _asyncRunCallbackLoop() 47 | _AsyncCallbackEntry entry = _nextCallback 48 | while(entry != null) { 49 | enry.callback(); 50 | entry = _nextCallback = entry.next; 51 | } 52 | 53 | 54 | _AsyncCallbackEntry next 55 | _AsyncCallback callback 56 | 57 | 58 | 59 | 'deferred_load_patch.dart', 60 | 'schedule_microtask_patch.dart', 61 | 'timer_patch.dart', 62 | 63 | 64 | class _AsyncRun { 65 | _scheduelImmediate(callback) 66 | //callback 67 | } 68 | 69 | 70 | _Timer 71 | 72 | async Timer 73 | 74 | 75 | 76 | 77 | 78 | 79 | =============================================================================== 80 | =============================================================================== 81 | =============================================================================== 82 | =============================================================================== 83 | 84 | ******************************************************************************* 85 | =============================================================================== 86 | =============================================================================== 87 | =============================================================================== 88 | -------------------------------------------------------------------------------- /DartVM/src/out/fibo.fibo.a2.ir: -------------------------------------------------------------------------------- 1 | ==== file:///home/elise/language/dart/work/adven/fibo.dart_::_fibo 2 | 0: B0[graph] { 3 | v0 <- Constant:29(#null) 4 | v1 <- Parameter:30(0) {PT: dynamic} {PCid: dynamic} 5 | } 6 | 2: B1[target] ParallelMove eax <- S-1 7 | 4: CheckStackOverflow:2() 8 | 6: v2 <- Constant:4(#2) {PT: _Smi@0x36924d72} {PCid: _Smi@0x36924d72} [2, 2] 9 | 8: CheckSmi:5(v1) env={ v1 [eax], v1 [eax], v2 [C] } 10 | 10: Branch if RelationalOp:5(<, v1, v2 IC[1: _Smi@0x36924d72, _Smi@0x36924d72 #588]) goto (2, 3) 11 | 12: B2[target] 12 | 13: ParallelMove eax <- eax 13 | 14: Return:8(v1) 14 | 16: B3[target] 15 | 18: v3 <- Constant:11(#1) {PT: _Smi@0x36924d72} {PCid: _Smi@0x36924d72} [1, 1] 16 | 20: ParallelMove ecx <- eax 17 | //v4 <- InstanceCall:13(-, v1, v3 IC[1: _Smi@0x36924d72, _Smi@0x36924d72 #309]) env={ v1, a0, a1 } 18 | 20: v4 <- BinarySmiOp:13(-, v1, v3) {PT: _Smi@0x36924d72} {PCid: _Smi@0x36924d72} [1, 1073741822] -o <-- Smi型に特殊化された中間表現 19 | 22: PushArgument:14(v4) {PCid: dynamic} 20 | //v5 <- StaticCall:15(fibo v4) env={ v1, a0 } 21 | 24: v5 <- StaticCall:15(fibo v4) {PT: dynamic} {PCid: dynamic} env={ v1 [S-1], a0 } 22 | 25: ParallelMove eax <- eax 23 | 26: ParallelMove ecx <- S-1, S+0 <- eax 24 | //v7 <- InstanceCall:21(-, v1, v6 IC[1: _Smi@0x36924d72, _Smi@0x36924d72 #278]) env={ v1, a0, a1, a2 } 25 | 26: v7 <- BinarySmiOp:21(-, v1, v2) {PT: _Smi@0x36924d72} {PCid: _Smi@0x36924d72} [0, 1073741821] -o <-- Smi型に特殊化された中間表現 26 | 28: PushArgument:22(v7) {PCid: dynamic} 27 | //v8 <- StaticCall:23(fibo v7) env={ v1, a0, a1 } 28 | 30: v8 <- StaticCall:23(fibo v7) {PT: dynamic} {PCid: dynamic} env={ v1 [S-1], v5 [S+0], a0 } 29 | 31: ParallelMove ecx <- eax, eax <- S+0 30 | 32: CheckSmi:25(v5) env={ v1 [S-1], v5 [eax], v8 [ecx] } 31 | 34: CheckSmi:25(v8) env={ v1 [S-1], v5 [eax], v8 [ecx] } 32 | 36: ParallelMove edx <- eax 33 | //v9 <- InstanceCall:25(+, v5, v8 IC[1: _Smi@0x36924d72, _Smi@0x36924d72 #274]) env={ v1, a0, a1 } 34 | 36: v9 <- BinarySmiOp:25(+, v5, v8) {PT: _Smi@0x36924d72} {PCid: _Smi@0x36924d72} [-inf, +inf] +o env={ v1 [S-1], v5 [eax], v8 [ecx] } <-- Smi型に特殊化された中間表現 35 | 37: ParallelMove eax <- edx 36 | 38: Return:26(v9) 37 | -------------------------------------------------------------------------------- /DartVM/src/os.rst: -------------------------------------------------------------------------------- 1 | runtime/vm 2 | debuginfo_android.cc 3 | gdbjit_android.h|cc 4 | os_android.cc 5 | virtual_memory_android.cc 6 | 7 | runtime/platform 8 | utils_android.h|cc 9 | thread_android.h|cc 10 | 11 | runtime/bin 12 | crypto_android.cc 13 | dbg_connection_android.h|cc 14 | directory_android.cc 15 | eventhandler_android.h|cc 16 | extensions_android.cc 17 | fdutils_android.cc 18 | file_android.cc 19 | platform_android.cc 20 | process_android.cc 21 | socket_android.h|cc 22 | utils_android.cc 23 | 24 | runtime/vm/os.h 25 | static const char* GetTimeZoneName(int64_t seconds_since_epoch); 26 | static int GetTimeZoneOffsetInSeconds(int64_t seconds_since_epoch); 27 | static int GetLocalTimeZoneAdjustmentInSeconds(); 28 | static int64_t GetCurrentTimeMillis(); 29 | static int64_t GetCurrentTimeMicros(); 30 | static word ActivationFrameAlignment(); 31 | static const int kMaxPreferredCodeAlignment = 32; 32 | static word PreferredCodeAlignment(); 33 | static uword GetStackSizeLimit(); 34 | static int NumberOfAvailableProcessors(); 35 | static void Sleep(int64_t millis); 36 | static void Print(const char* format, ...) PRINTF_ATTRIBUTE(1, 2); 37 | static void PrintErr(const char* format, ...) PRINTF_ATTRIBUTE(1, 2); 38 | static void VFPrint(FILE* stream, const char* format, va_list args); 39 | static int SNPrint(char* str, size_t size, const char* format, ...) PRINTF_ATTRIBUTE(3, 4); 40 | static int VSNPrint(char* str, size_t size, const char* format, va_list args); 41 | static bool StringToInt64(const char* str, int64_t* value); 42 | static void InitOnce(); 43 | static void Shutdown(); 44 | static void Abort(); 45 | static void Exit(int code); 46 | 47 | runtime/bin 48 | crypto_android.cc 49 | dbg_connection_android.cc 50 | dbg_connection_android.h 51 | directory_android.cc 52 | eventhandler_android.cc 53 | eventhandler_android.h 54 | extensions_android.cc 55 | fdutils_android.cc 56 | file_android.cc 57 | platform_android.cc 58 | process_android.cc 59 | socket_android.cc 60 | socket_android.h 61 | utils_android.cc 62 | 63 | 64 | localtime_r() 65 | tzset() 66 | gettimeofday() 67 | getrlimit() 68 | sysconf(_SC_NPROCESSORS_ONLN) 69 | usleep() 70 | vfprintf() 71 | vsnprintf() 72 | va_start() 73 | va_end() 74 | strtoll() 75 | exit() 76 | 77 | getpagesize() 78 | mmap() 79 | munmap() 80 | unmap() 81 | mprotect() 82 | -------------------------------------------------------------------------------- /DartVM/src/advent201212index.rst: -------------------------------------------------------------------------------- 1 | Dart VM index 2 | ############################################################################### 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | 7 | advent20121201 8 | advent20121202 9 | advent20121203 10 | advent20121204 11 | advent20121205 12 | advent20121207 13 | advent20121208 14 | advent20121209 15 | advent20121210 16 | advent20121211 17 | advent20121212 18 | advent20121213 19 | advent20121214 20 | advent20121215 21 | advent20121216 22 | advent20121217 23 | advent20121218 24 | advent20121219 25 | advent20121220 26 | advent20121221 27 | advent20121223 28 | advent20121224 29 | advent201212todo 30 | todo 31 | gc03 32 | 33 | 努力目標 34 | =============================================================================== 35 | 内容は予告なしに変更される可能性があります。 36 | 37 | - Dart VMの魅力 38 | - Dart VMのビルド方法 39 | - Dart VMのオプション 40 | - Dart VMの概要1 41 | - Dart VMの概要2 42 | - Dart VMの概要3 43 | - Dart VMと他VMとの比較 44 | - Perf Profiling 45 | - Dart VMのGC overview 46 | - ExecutionCodeとRuntimeの連携 47 | - FlowGraphCompiler overview 48 | - Benchmark & performance tuning 49 | - FlowGraphCompiler intermediate representation 50 | - dart core api scalarlist vs. List 51 | - dart core api scalarlist mcro & intrinsic 52 | - Dart VMのGC Scavenger 53 | - Dart API Layer 54 | - intrinsics string 55 | - FlowGraphCompiler gvn & cse 56 | - FlowGraphCompiler licm 57 | - core api layer(String) 58 | - Dart Architecture 59 | - Dart VM Architecture 60 | 61 | 候補 62 | 63 | - 01 Dart VM src overview 64 | - 02 Isolate and Startup 65 | - 03 Memory layout 66 | - 04 Message passing & Snapshot 67 | - 05 Dart VM Native extension 68 | 69 | - 06 Dart VM Performance 70 | - 07 Dart Numeric Computation 71 | http://news.dartlang.org/2013/06/faster-is-better-new-article-on-numeric.html 72 | 73 | - 08 Dart VMのGC Mark&Sweep 74 | - 09 OptionalTypes1 (dynamic) 75 | - 10 OptionalTypes2 (generics) 76 | 77 | - 11 InlineCaching & Stubs 78 | - 12 FlowGraphCompiler6 inlining 79 | 80 | - 13 Dart VMのGC Root Reference & Handles 81 | - 14 Dart VMのGC Extended, Weak, Peer, External, old->new pointers 82 | 83 | - Deoptimization Framework 84 | 85 | - FlowGraphCompiler3 type inference 86 | - FlowGraphCompiler4 boxing-unboxing & representation 87 | - FlowGraphCompiler7 register allocation 88 | 89 | - intrinsics3 list, map 90 | - Runtime3 hotcode & unoptimized path 91 | - Runtime4 Deoptimization & Stackmaps 92 | -------------------------------------------------------------------------------- /Ethereum/asm.rst: -------------------------------------------------------------------------------- 1 | 2 | EVM 3 | ####### 4 | 5 | https://github.com/comaeio/porosity/wiki/Ethereum-Internals 6 | 7 | core/vm 8 | instructions.go 9 | 10 | accountは以下を管理していることを前提とする 11 | balance, nonce, codeHash(contract専用), storageRoot 12 | 13 | 以下の領域が存在する 14 | 15 | code //readonly 16 | stack 17 | memory 18 | storage //永続化対象, 256bit=32byte単位のkvs 19 | calldata 20 | returndata 21 | 22 | stackは256bit単位, 最大で1024 element 23 | 24 | memory 25 | ######### 26 | 27 | 0x00 〜 0x3f: スクラッチ領域。storageに定義された配列の要素の先頭アドレスを求める時とかに使われる。直ぐ消えてもいいデータを扱う領域。 28 | 0x40 〜 0x5f: フリーメモリのポインタ。この領域に格納されたアドレス以降が未使用のメモリ領域。メモリをアロケートする場合はここの値が増えていく。 29 | 0x60 〜 0x7f: 常に0で、dynamic memory arrayの初期化に使われるらしい。この領域を参照しているopcodeは見たことないので具体的にどういう時に使われるのかはよくわからない。 30 | 0x80 〜 : これ以降は全てフリーメモリ。 31 | 32 | storage opcode 33 | ########## 34 | https://y-nakajo.hatenablog.com/entry/2018/06/03/165658 35 | 36 | stack 37 | PUSH01〜PUSH32: 次に続く1〜32byteのデータをstackの先頭に積みます 38 | DUP1〜DUP16: stack上の1〜16番目の値をコピーしてstackの先頭に積みます 39 | POP: stackの先頭のデータを取り除きます 40 | SWAP1〜SWAP16: stack上の2〜17番目のデータと先頭のデータを入れ替えます。 41 | ADD, SUB, MOD, MUL, EXP, ADDMOD, MULMOD: 四則演算系のopcode 42 | 43 | memory //memory修飾子, 3gas 44 | MSTORE(p, v); pを先頭アドレスとしてp+32の32byte領域にvの値を格納します。 45 | MSTOREB(p, v); pの位置にv & 0xffの1byteデータを格納します。 46 | MLOAD(p): pを先頭アドレスしてp+32までの32byteの値をロードしてstackの先頭に積みます。 47 | 48 | storage //永続化 49 | SSTORE(p, v): storageのpの位置に32byteのv値を格納します。 50 | SLOAD(p): storageのpの位置から32byteの値をロードしstackの先頭に積みます。 51 | 52 | calldata //functionの引数を格納するための領域 53 | calldatasize: calldataに格納されたデータサイズをstackの先頭に積みます。 54 | calldataload(p): calldataのpの位置からp+32の位置までの32byteのデータをstackの先頭に積みます。 55 | calldatacopy(t, f, s): calldata領域のfの位置からsで指定されたサイズ(s bytes)のデータをmemory tの位置にコピーします。つまり、メモリのt〜t+sまでの間にコピーします。 56 | 57 | returndata //他のContractの関数を呼び出したときの返却データの格納先 58 | returndatasize: returndataに格納されているデータのサイズをstackの先頭に積みます。 59 | returndatacopy(t, f, s): returndata領域のfの位置からsで指定されたサイズ(s bytes)のデータをmemory tの位置にコピーします。つまり、メモリのt〜t+sまでの間にコピーします。 60 | 61 | storage gas 62 | ############### 63 | Ethereumではstorageにデータを格納する場合、32byteごとにgas代がかかります。 64 | 20000gas //初回strage書き込み 65 | 21000gas //transaction gas 66 | 67 | zero -> non zero: (NEW VALUE) cost 20000gas 68 | non zero -> zero: (DELETE) refund 15000gas、 cost 5000gas 69 | non zero -> non zero: (CHANge) cost 5000gas 70 | read 200gas 71 | 72 | memory read/write 3gas 73 | 74 | truffle opmizeすると32byteに押し込むらしい。 75 | 76 | ABI 77 | #################### 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /DartVM/src/storebarrier.rst: -------------------------------------------------------------------------------- 1 | DLRT_StoreBufferBlockProcess 2 | StoreBuffer 3 | 4 | : void StoreBufferBlock::ProcessBuffer(Isolate* isolate) { 5 | : StoreBuffer* buffer = isolate->store_buffer(); 6 | : int32_t end = top_; 7 | 0.00 : 81d20a8: mov %edx,0x18(%esp) 8 | : for (int32_t i = 0; i < end; i++) { 9 | 0.00 : 81d20ac: jle 81d2137 10 | 0.00 : 81d20b2: movl $0x0,0x10(%esp) ▒ 11 | 0.00 : 81d20ba: lea 0x0(%esi),%esi ▒ 12 | : buffer->AddPointer(pointers_[i]); ▒ 13 | 0.13 : 81d20c0: mov 0x10(%esp),%edx ▒ 14 | 48.83: 81d20c4: mov 0x1c(%esp),%eax ▒ 15 | 0.00 : 81d20c8: mov 0x4(%eax,%edx,4),%esi ▒ 16 | : Isolate::Current()->ScheduleInterrupts(Isolate::kStoreBufferInterrupt); ▒ 17 | : } ▒ 18 | : } ▒ 19 | : } 20 | 21 | StoreBufferBlock::AddPointer(uward) 22 | ProcessBuffer() 23 | ProcessBuffer(Isolate*) 24 | buffer->AddPointer(uward) 25 | Isolate::Current()->ScheduleInterrupts(Isolate::kStoreBufferInterrupt) 26 | 27 | StoreBufferBlock::AddPointer(uward) 28 | <-- gc_marker.cc::MarkObject(RawObject*, RawObject**) 29 | <-- scavenger.cc:UpdateStoreBuffer() 30 | 31 | 32 | bool Value::NeedsStoreBuffer() const { 33 | const intptr_t cid = ResultCid(); 34 | if ((cid == kSmiCid) || (cid == kBoolCid) || (cid == kNullCid)) { 35 | return false; 36 | } 37 | return !BindsToConstant(); 38 | } 39 | 40 | intermediate_language.h: bool NeedsStoreBuffer() const; 41 | intermediate_language.h: return value()->NeedsStoreBuffer() && emit_store_barrier_; 42 | 43 | -------------------------------------------------------------------------------- /DartVM/src/vmservice.rst: -------------------------------------------------------------------------------- 1 | vmservice 2 | ############################################################################### 3 | 4 | dart vm --enable-vm-service 5 | default:localhost:8181 6 | 7 | 8 | ******************************************************************************* 9 | 10 | main.cc 11 | =============================================================================== 12 | 13 | :: 14 | 15 | // VM Service options. 16 | // main.cc 17 | static bool start_vm_service = false; 18 | static int vm_service_server_port = -1; 19 | static const int DEFAULT_VM_SERVICE_SERVER_PORT = 8181; 20 | 21 | //dartコマンドのオプション 22 | dart options 23 | --enable-vm-service 24 | 25 | // main.cc 26 | // Start the VM service isolate, if necessary. 27 | if (start_vm_service) { 28 | bool r = VmService::Start(vm_service_server_port); 29 | Dart::Thread::Start(ThreadMain, server_port); 30 | 31 | 32 | // vmservice_impl.cc 33 | static const char* kVMServiceIOLibraryScriptResourceName = 34 | kLibraryResourceNamePrefix "/vmservice_io.dart"; 35 | static const char* kVMServiceLibraryName = 36 | kLibraryResourceNamePrefix "/vmservice.dart"; 37 | 38 | _Start() 39 | isolate_ = Dart_CreateIsolate("vmservice:", "main", ...); 40 | LoadScript(kVMServiceIOLibraryScriptResourceName); 41 | 42 | vmservice_io 43 | =============================================================================== 44 | 45 | いま風にhtmlで起動ですか。 46 | 47 | :: 48 | 49 | // Create VmService. 50 | var service = new VMService(); 51 | // Start HTTP server. 52 | var server = new Server(service, _port); 53 | server.startServer(); 54 | 55 | 56 | VMService 57 | =============================================================================== 58 | 59 | :: 60 | 61 | _requestHandler(HttpRequest request) 62 | 63 | 64 | serviceRequest.parse() 65 | 66 | reqはmap形式、 67 | 68 | type 69 | msg 70 | pathSegments 71 | parameters 72 | 73 | 実験方法 74 | =============================================================================== 75 | 76 | localhost:8181 77 | 78 | へアクセス 79 | 80 | /type 81 | 82 | http://localhost:8181/?stacktrace=off 83 | 84 | 85 | デバッグ情報を歯根でも上記までいかないということは、 86 | 途中でつまっているということ。 87 | 88 | runtime/vm 89 | =============================================================================== 90 | 91 | Future route(ServiceRequest request) 92 | sendMessage(List request) 93 | sendServiceMessage(sp, rp, m) 94 | native "SendServiceMessage"; 95 | -------------------------------------------------------------------------------- /DartVM/src/osr.rst: -------------------------------------------------------------------------------- 1 | On-Stack Replacement 2 | ############################################################################### 3 | 4 | Revision 5 | =============================================================================== 6 | r24088 | kmillikin@google.com | 2013-06-17 20:05:15 +0900 (月, 17 6月 2013) | 12 lines 7 | 8 | After OSR compilation, restore the pre-OSR code (which might be already 9 | optimized) rather than the unoptimized code (which might have its entry patched). 10 | When the optimized code entry is patched it is only safe to call 11 | it as a static call, not as an instance call. 12 | 13 | 14 | r24024 | kmillikin@google.com | 2013-06-14 19:10:55 +0900 (金, 14 6月 2013) | 13 lines 15 | OSRの最初の実装 16 | プロファイリングを追加 OSRの候補を選択する 17 | 関数にOSR entry pointを追加 18 | 19 | パラメータのプロファイルとって 20 | チューニング中、 21 | 22 | Option 23 | =============================================================================== 24 | オプションを3つ追加 25 | 26 | DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement."); 27 | DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement."); 28 | 29 | Assembler 30 | =============================================================================== 31 | Assembler::EnterOsrFrame(intptr_t extra_size)の追加 32 | 33 | code_generator::StackOverflowを修正 34 | 35 | CompileParsedFunctionの引数、osr_idを追加 36 | osr_idがkNoDeoptIdの場合、これまでの処理と同様。デフォルト値みたいなもん。 37 | 38 | AddCurrentDescriptorには、osr用 39 | 40 | PcDescriptor 41 | =============================================================================== 42 | PcDescriptorには、kOsrEntryを追加。 43 | 44 | OSRの場合、通常のFrameEnterよりStackSizeが小さい。 45 | intptr_t extra_slots = StackSize() 46 | - flow_graph().num_stack_locals() 47 | - flow_graph().num_copied_params(); 48 | 49 | class Codeに、intptr_t GetDeoptIdForOsr(uword pc) const; を追加 50 | 51 | GraphBuilderから、 52 | GraphEntry->PruneUnreachable() 53 | osr_id == deoptidのブロックを、深さ優先で探す。 54 | 対象のAsJoinEntryからGotoInstrを生成し、Edgeを生成する。 55 | 56 | 上記を使って、GraphBuilderにおいて、GraphEntryのSucc > 1のポイントに、 57 | OSR用のedgeを挿入していく。 58 | 59 | Check <-- CheckStackOverflow 60 | Compile 61 | OSR Patch 62 | 63 | Entry 64 | =============================================================================== 65 | 66 | StackOverflowにおいて、 67 | usage_counterを+1する。これは以前から同様。 68 | 69 | UnoptimizedCodeにおいて、StackOverflowした場合、 70 | 具体的にはRuntimeEntry中において、 71 | OSRを試行する。 72 | 73 | AddCurrentDescriptor 74 | =============================================================================== 75 | 76 | 77 | -------------------------------------------------------------------------------- /Pyston/0_1.rst: -------------------------------------------------------------------------------- 1 | src 2 | ############################################################################### 3 | 4 | 見どころは 5 | 6 | types.h 7 | 8 | 構成 9 | ******************************************************************************* 10 | 11 | src :: 12 | 13 | analysis 14 | asm_writing 15 | codegen 16 | irgen 17 | opt 18 | profiling 19 | core 20 | gc 21 | runtime 22 | builtin_modules 23 | inline 24 | 25 | main :: 26 | 27 | jit.cpp 28 | 29 | BoxedModule* main = createMainModule(fn); 30 | CompiledFunction* compiled = compileModule(m, main); 31 | interpretFunction(compiled->func,0,...); 32 | (compiled->code)(); 33 | 34 | analysis 35 | =============================================================================== 36 | BBTypePropagator 37 | 38 | processSpeculation 39 | 40 | PropagatingTypeAnalysis 41 | 42 | 43 | 44 | 45 | core/type 46 | =============================================================================== 47 | 48 | GCObjectHeader 49 | 50 | GCObject 51 | 52 | HiddenClass 53 | 54 | Box 55 | 最初にclsフィールドが埋まっている。Boxメソッドが実装されている。 56 | 57 | 58 | 59 | codegen/irgen 60 | =============================================================================== 61 | 62 | optimizeIR() 63 | 64 | makeFPInliner 65 | EscapeAnalysis 66 | createPystonAAPass 67 | 68 | createMAllocsNonNullPass() 69 | 70 | vector系はほぼほぼoffと 71 | 72 | ENABLE_PYSTON_PASSES 73 | ConstClassesPass 74 | DeadAllocsPass 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | codegen/profiling 83 | =============================================================================== 84 | 85 | =============================================================================== 86 | =============================================================================== 87 | 88 | =============================================================================== 89 | 90 | ******************************************************************************* 91 | 92 | =============================================================================== 93 | =============================================================================== 94 | 95 | template :: 96 | ############################################################################### 97 | ******************************************************************************* 98 | =============================================================================== 99 | 100 | -------------------------------------------------------------------------------- /DartVM/src/specialize.rst: -------------------------------------------------------------------------------- 1 | 2 | 特殊化 3 | 4 | 案1 IC smi double 5 | optimizeの際に、ICから取得した型だけ参照するのはよろしくないのかもしれない。 6 | 7 | メソッドをコピるか 8 | 呼び出しをどんどんクローンしていくか? 9 | T型のクラスごとに、クローンだけしてメソッドをよびわけるか 10 | よびわけてクローンするだけで、ICの型の履歴は1つに定まるはず 11 | 12 | 案2 obj作った際の実行時に行う。 13 | Allocate Object TypeArgumentsの引数の型を取得する。 14 | その際に、型をつかって、クラス単位で特殊化する。??? 15 | 16 | 案3 17 | 18 | 19 | Materialize命令は、定数の初期化をlazyに扱うためにあるのか? 20 | 21 | ==== file:///home/elise/language/dart/work/basic/sp.dart_Gen_getRec 22 | 0: [graph] 23 | { 24 | v0 <- parameter(0) 25 | v1 <- parameter(1) 26 | } env={ v0, v1, #null } 27 | 1: [target] 28 | CheckStackOverflow:0() env={ v0, v1, #null } 29 | v2 <- Materialize:1(#null) env={ v0, v1, #null } 30 | PushArgument v0 env={ v0, v1, #null, v1, v0 } 31 | v3 <- InstanceCall:5(get:init, v0) IC[1: Gen] env={ v0, v1, #null, v1, t-1 } 32 | Branch:7 if v1 > v3 goto (2, 3) IC[=2: Smi, Smi | Double, Double] env={ v0, v1, #null, v1, v3 } 33 | 2: [target] 34 | PushArgument v1 env={ v0, v1, #null, v1 } 35 | PushArgument v0 env={ v0, v1, #null, t-1, v0 } 36 | PushArgument v1 env={ v0, v1, #null, t-1, t-1, v1 } 37 | PushArgument v0 env={ v0, v1, #null, t-1, t-1, t-1, v0 } 38 | v6 <- InstanceCall:12(get:init, v0) IC[1: Gen] env={ v0, v1, #null, t-1, t-1, t-1, t-1 } 39 | PushArgument v6 env={ v0, v1, #null, t-1, t-1, t-1, v6 } 40 | v7 <- InstanceCall:13(-, v1, v6) IC[=2: Smi, Smi | Double, Double] env={ v0, v1, #null, t-1, t-1, t-1, t-1 } 41 | PushArgument v7 env={ v0, v1, #null, t-1, t-1, v7 } 42 | v8 <- InstanceCall:14(getRec, v0, v7) IC[1: Gen] env={ v0, v1, #null, t-1, t-1, t-1 } 43 | PushArgument v8 env={ v0, v1, #null, t-1, v8 } 44 | v9 <- InstanceCall:15(* , v1, v8) IC[=2: Smi, Smi | Double, Double] env={ v0, v1, #null, t-1, t-1 } 45 | goto 4 env={ v0, v1, v9 } 46 | 3: [target] 47 | PushArgument v0 env={ v0, v1, #null, v0 } 48 | v4 <- InstanceCall:18(get:init, v0) IC[1: Gen] env={ v0, v1, #null, t-1 } 49 | goto 4 env={ v0, v1, v4 } 50 | 4: [join] 51 | v5 <- phi(v4, v9) 52 | Return:21 v5 env={ v0, v1, v5, v5 } 53 | 54 | 呼び出し箇所 55 | v37 <- InstanceCall:55(%, v35, v36) IC[1: Double, Double] env={ v18, v1, v1, v4, v4, v9, v9, v14, v14, v19, v29, v21, v22, v23, t-1, t-1, t-1 } 56 | PushArgument v37 env={ v18, v1, v1, v4, v4, v9, v9, v14, v14, v19, v29, v21, v22, v23, t-1, v37 } 57 | v38 <- InstanceCall:56(getRec, v4, v37) IC[1: NoGen] env={ v18, v1, v1, v4, v4, v9, v9, v14, v14, v19, v29, v21, v22, v23, t-1, t-1 } 58 | 59 | -------------------------------------------------------------------------------- /golang/runtime.rst: -------------------------------------------------------------------------------- 1 | pkg/runtime/runtime 2 | ############################################################################### 3 | 4 | 主要なruntimeの関数の実装を追う 5 | 6 | sched系 7 | ******************************************************************************* 8 | 9 | gosched(void) and gosched0(G*) 10 | =============================================================================== 11 | 12 | =============================================================================== 13 | =============================================================================== 14 | =============================================================================== 15 | 16 | 17 | time.Sleep() 18 | =============================================================================== 19 | 20 | src/pkg/time/Sleep.goの中身は、Cの関数の宣言のみだった。 21 | 22 | runtime/time.goc:func Sleep(ns int64) :: 23 | runtime..tsleep(ns, "sleep") 24 | 25 | Timer t; 26 | if(ns <= 0) 27 | return; 28 | t.when = runtime·nanotime() + ns; 29 | t.period = 0; //timerproc()での監視間隔 30 | t.fv = &readyv; 31 | t.arg.data = g; 32 | runtime·lock(&timers); 33 | addtimer(&t); 34 | runtime·parkunlock(&timers, reason); 35 | 36 | //parkunlockの第1引数はlock済みのオブジェクトなのか? 37 | 38 | // Puts the current goroutine into a waiting state and unlocks the lock. 39 | // The goroutine can be made runnable again by calling runtime·ready(gp). 40 | void 41 | runtime·parkunlock(Lock *lock, int8 *reason) 42 | { 43 | runtime·park(parkunlock, lock, reason); 44 | } 45 | 46 | 47 | 48 | 49 | =============================================================================== 50 | =============================================================================== 51 | =============================================================================== 52 | =============================================================================== 53 | =============================================================================== 54 | 55 | 56 | ******************************************************************************* 57 | 58 | =============================================================================== 59 | =============================================================================== 60 | 61 | template :: 62 | ############################################################################### 63 | ******************************************************************************* 64 | =============================================================================== 65 | 66 | -------------------------------------------------------------------------------- /DartVM/src/advent20121201.rst: -------------------------------------------------------------------------------- 1 | Dart VM Advent Calendar 2012 12/01 2 | ############################################################################### 3 | 4 | これが最新のVMだ! 5 | 6 | 断じてV8からjavascript向け最適化を取り除いたVMではない。 7 | 8 | .. image:: png/dart.png 9 | 10 | Dart VMの魅力 11 | ============================================================================== 12 | 13 | Dart VMの最大の魅力は、速さへのこだわりです。 14 | 15 | 既にV8より10倍高速に起動し、将来的には2倍高速に動作するのを目指しているようです。 16 | 17 | ここ十年のVMとJITコンパイラ系の技術の進化は素晴らしくて、 18 | JavaScriptにどのくらい性能向上できる余地が残っているのか、 19 | 何がボトルネックなのかが見えているのだと思います。 20 | 21 | そして、その壁をECMAScriptの仕様改善により進化させていくことも可能だと思います。 22 | 23 | 私には、さらなる性能向上を目指したVMのDesignと、 24 | 性能向上を優先した上で柔軟な言語仕様を提供しようとしている 25 | Dart VMとDartが非常に魅力的に映ります。 26 | 27 | Dart VMの性能 28 | ============================================================================== 29 | いくつかV8より高速に動作するベンチマークもぼちぼち出てきたようです。 30 | 31 | .. image:: png/dart_bench.png 32 | 33 | score表示であり、緑色が優れています。 34 | 35 | DeltaBlueやRichardsは、octane-benchmarkにも含まれているもので、 36 | 以下のdart benchmark harnessから試すことができます。 37 | 38 | https://github.com/dart-lang/benchmark_harness 39 | 40 | 41 | Dart VMは、上記にあげたいくつかのベンチマークで、V8よりも高速に動作するようです。 42 | 43 | とはいえ、上記にあげた大部分はマクロベンチマークで、部分的な比較でしかないよう思います。 44 | 45 | 中規模のベンチマークであるoctaneに関しても、上記にあげた2つ以外は、V8のほうが速いと予想します。 46 | 47 | 現在のV8とDart VMを比較すると、文字列や乱数を使用するベンチマークは、V8のほうが高速なはずです。 48 | 49 | Dart VMが高速に動作するケースは、Array(主にscalarlist)を使用するものや、 50 | premitive型に落ちやすい要素が多いベンチマークなのかな?と思っています。 51 | 52 | VMの匠 53 | ============================================================================== 54 | 55 | VMの匠、Lars Bak氏 26年ってすごいと思います。 56 | 57 | 氏と、最先端のVMチームの経験に学ばせていただこうかなと。。 58 | 59 | この資料が詳しいです。 60 | 61 | http://www.dartlang.org/slides/2012/09/strangeloop/pushing-the-limits-of-web-browsers-lars-bak.pdf 62 | 63 | Dartの言語仕様 64 | ============================================================================== 65 | 66 | dartの言語仕様をsmalltalkと比較した紹介資料です。 これがわかりやすい。 67 | 68 | http://www.dartlang.org/slides/2012/03/smalltalk-industry-conference/DARTtalk-20120319.pdf 69 | 70 | 気になるところは、 71 | 72 | (1) not support eval. 73 | 性能を優先した妥協点なのだと思います。 74 | 75 | (2) Classes is not first class objects. 76 | 関数はfirst class objectです。 77 | 78 | そのため、isolateのmessage passingも関数単位で記述します。 79 | 80 | Classesをmessage passingできたら便利かもなーと、 81 | isolateを書いていて思うことはありますね。 82 | 83 | (3) mirror based reflection. Fields can’t be added dynamically. 84 | 動的に追加できたらjavascript似たりよったりで同じ問題が起こるように思います。 85 | 86 | 性能を優先した妥協点なのだと思います。 87 | 88 | 個人的には、 89 | List内包表記、pattern matching、eval、yield、型推論のような機能が欲しいですよね。。 90 | 91 | 大体はdartが発表された2011/11にdart discussionに突撃して、 92 | そんな機能はないよ -> dart言語設計センスない、、 93 | と言われるところにつながっているのかも。 94 | -------------------------------------------------------------------------------- /golang/memory.rst: -------------------------------------------------------------------------------- 1 | memory 2 | ############################################################################### 3 | 4 | channel and goroutine 5 | qsize = 100 6 | 7 | 10,000 8 | Sys=4102 kb,TotalAlloc=211 kb,HSys=1024 kb, HAlloc=211 kb 9 | Sys=15258 kb,TotalAlloc=10495 kb,HSys=11264 kb, HAlloc=10477 kb 10 | Sys=98538 kb,TotalAlloc=13811 kb,HSys=14336 kb, HAlloc=13658 kb 11 | 12 | 100,000 13 | Sys=4102 kb,TotalAlloc=211 kb,HSys=1024 kb, HAlloc=211 kb 14 | Sys=117094 kb,TotalAlloc=102957 kb,HSys=103424 kb, HAlloc=102939 kb 15 | Sys=957122 kb,TotalAlloc=135486 kb,HSys=135168 kb, HAlloc=133856 kb 16 | 17 | qsize = 1 18 | 10,000 19 | Sys=4102 kb,TotalAlloc=211 kb,HSys=1024 kb, HAlloc=211 kb 20 | Sys=5190 kb,TotalAlloc=1261 kb,HSys=2048 kb, HAlloc=1243 kb 21 | Sys=88585 kb,TotalAlloc=4568 kb,HSys=5120 kb, HAlloc=4387 kb 22 | 23 | 100,000 24 | Sys=4102 kb,TotalAlloc=210 kb,HSys=1024 kb, HAlloc=209 kb 25 | Sys=16282 kb,TotalAlloc=10635 kb,HSys=11264 kb, HAlloc=10618 kb 26 | Sys=854954 kb,TotalAlloc=43157 kb,HSys=43008 kb, HAlloc=41598 kb 27 | chan 12M, heap10M, chan120byte 28 | g 840M, 8.4kByte 29 | 30 | 200,000 31 | Sys=4102 kb,TotalAlloc=211 kb,HSys=1024 kb, HAlloc=211 kb 32 | Sys=29078 kb,TotalAlloc=21052 kb,HSys=22080 kb, HAlloc=21034 kb 33 | Sys=1706710 kb,TotalAlloc=86091 kb,HSys=84544 kb, HAlloc=83146 kb 34 | 35 | golang 1chanが120byte程度、1goroutineが8.4kbyte程度か、goroutineは8kbyteのstackとすると、goroutineの管理領域は400byte程度か。これならメモリさえ用意すれば100万ノードのシミュレーションも難しくないかも。。 36 | 37 | 全員へのbroadcastは、 38 | 10,000で、3ms 39 | 100,000で47msくらい。 40 | 200,000で96msくらい。 41 | 42 | 43 | //go1.3 44 | WARN: 2014/04/24 08:19:11 main.go:189: Sys=3974 kb,TotalAlloc=118 kb,HSys=1024 kb, HAlloc=118 kb 45 | WARN: 2014/04/24 08:19:11 main.go:189: Sys=24854 kb,TotalAlloc=18377 kb,HSys=19456 kb, HAlloc=18362 kb 46 | WARN: 2014/04/24 08:19:11 main.go:189: Sys=54510 kb,TotalAlloc=46252 kb,HSys=47104 kb, HAlloc=46232 kb 47 | 48 | 49 | go1.3でgoroutineのstackが4kbになった。 50 | 51 | 52 | 参照箇所は 53 | segment stackは4kbになっていた。src/pkg/runtime/stack.hのStackMin = 4096 54 | 55 | 56 | ############################################################################### 57 | 58 | ******************************************************************************* 59 | ******************************************************************************* 60 | 61 | =============================================================================== 62 | =============================================================================== 63 | 64 | template :: 65 | ############################################################################### 66 | ******************************************************************************* 67 | =============================================================================== 68 | 69 | -------------------------------------------------------------------------------- /erlang/todo.rst: -------------------------------------------------------------------------------- 1 | 疑問点とか、調べたいこと 2 | ############################################################################### 3 | 4 | * low laytencyの仕組み 5 | 6 | GCがerlang process単位でincremental GC。全体を止めないようになっている。 7 | 8 | erlang processのscheduler兼インタプリタを自前で書いており、 9 | 自由に割り込み、wakeup、context switchできるようになっている。 10 | 11 | asyncの処理と割り込みは、async専用のthreadを立てて実行できるようになっている。デフォ10thread。 12 | 13 | message passingはerlang process単位にqueueを用意し、順番にdequeueして実行。 14 | 15 | * erlang processの仕組み。 16 | 17 | OSのprocessに 1 VMを立てる。 VM内では複数のthreadを立てて、schedulerやasyncを割り振る。 18 | 19 | OSのThreadは、起動時に20~23程度起動する。 20 | 21 | erlang processは、OSのthreadやprocessとは別もので、独自生成、独自管理。 22 | 23 | processのリソース管理は、malloc/free 24 | 25 | * プロセス間通信の仕組み process間、ノード間は? 26 | 27 | 基本はmessage passing。process間はlock 相手のqueueに送って、unlock。 erl_message参照 28 | 29 | ノード間もmessage passingだが、ノード間の場合はencode/decodeした上で、 30 | 相手ノードのportにmessageを送信する。 31 | 32 | ノードは、host名とportから構成されており、NodeListみたいのでVMが管理している。 33 | 34 | * 故障時の復帰方法 35 | 36 | VM内に別Threadで立っているsupervisorがcode indexを使用し、別erlang processへ復帰処理を行う。 37 | 38 | code indexは、hot loading, hot paching, upgradeの仕組みを提供している。 39 | 40 | VMごと落ちた場合はどうしようもないため、他のNodeからlinkをはったり、生死監視する必要がある。 41 | 42 | * 異なるアーキテクチャ間のserialization format 43 | 44 | external参照。encode/decode 45 | 46 | * asyncの仕組み 47 | 48 | VM内にasync_mainで別スレッドを立てて、いつでもasync処理を受けれるようになっている。 49 | 50 | ### todo 51 | 52 | link機能に関して 53 | 54 | lock/unlockの仕組み。 55 | 56 | 57 | Q 58 | =============================================================================== 59 | * 分散キーバリューストアには、JVMとErlangで組まれたものが多い。 その違いは 60 | 61 | Erlangのほうは高信頼性で、JVMはそこそこの性能重視なのかも。 62 | 63 | 分散、かつ高信頼なシステムを作る場合、ErlangのほうがOTP用のライブラリが揃っており、作り易い。 64 | 65 | * JVM系の言語は、運用のし易いさや保守性、信頼性、セキュリティをJVMに依存している。 66 | Erlangの高信頼性を支えることに、VMは寄与しているのか? 67 | 68 | ErlangのBEAM VM内にはsupervisorが存在し、erlang process間の障害を監視して回復できる。 69 | 70 | linkもVMの機能のような気がする。 71 | 72 | erlang processレベルの障害がどの程度あるのかは不明。 73 | supervisorで監視、復帰処理をしているが、その点はErlangとJVMの違い。 74 | 75 | armstrongから一言 76 | =============================================================================== 77 | 78 | * soft real-time 79 | * fault-tolerant systems 80 | * upgrad without taking them out of service 81 | 82 | * 各プロセスに張り付いた高速なGC 83 | * コードを適切に変更する(古いコードと新しいコードが共存できたりするよ) 84 | * 直交したエラー検知のメカニズム (catch-throw/links/ ...) 85 | * プラットフォームに依存したいエラー検知と回復 86 | (ie to make something fault tolerant needs at least 2 machines, 87 | think the case when one machine crashes - the second machine must be able to take over) 88 |   89 | * 分散プリミティブとか、分散ベータベース 90 | * サーバー壊れてもtake over 91 | * 故障モデル、コード変更、コード移動、無停止アップグレード 92 | 93 | 94 | template :: 95 | 96 | ############################################################################### 97 | ******************************************************************************* 98 | =============================================================================== 99 | -------------------------------------------------------------------------------- /DartVM/src/string.rst: -------------------------------------------------------------------------------- 1 | 内部ではlatin-1とutf-16で管理しているのかな。 2 | 2bytestringってのがいる。 3 | 4 | 5 | Improving string performance is a critical goal for the VM team this quarter, as it looks like that's perhaps the biggest advantage V8 has over Dart in the Dromaeo benchmarks. You can't have fast DOM performance with slow string support. 6 | 7 | We're moving to both 1-byte and 2-byte raw string encodings that match WebKit's, because right now any string shared between Dart and WebKit needs to be converted each way. Strings that don't require UTF-16 will use UTF-8, plus the Dartium engineers have requested support for known ASCII strings to avoid encoder overhead. 8 | 9 | 10 | r14989 | asiva@google.com | 2012-11-16 09:13:18 +0900 (金, 16 11月 2012) | 3 lines 11 | Revert OneByteString back to ISO Latin-1 instead of ASCII 12 | as webkit supports ISO Latin-1 and UTF-16 encodings for strings. 13 | Review URL: https://codereview.chromium.org//11365243 14 | 15 | 16 | r14887 | sgjesse@google.com | 2012-11-14 22:01:57 +0900 (水, 14 11月 2012) | 15 lines 17 | Add support for non ASCII strings when communicating with native ports. 18 | The string representation in a Dart_CObject strructure is now UTF8. 19 | All strings read are now converted to UTF8 from either ASCII or UTF16 serialization. 20 | All strings posted should be valid UTF8 and are 21 | serialized as either ASCII or UTF16 depending on the content. 22 | Proper andling of surrogate pairs is missing, but will be added when 23 | https://codereview.chromium.org/11368138/ lands. 24 | R=ager@google.com, erikcorry@google.com, asiva@google.com 25 | Review URL: https://codereview.chromium.org//11410032 26 | 27 | 28 | r14357 29 | Issue 11275008: - Represent strings internally in UTF-16 format, this makes it (Closed) 30 | 31 | Description 32 | - Represent strings internally in UTF-16 format, this makes it 33 | compatible with webkit and will allow for easy externalization of strings 34 | (The language specification was changed recently to reflect this as 35 | follows "A string is a sequence of UTF-16 code units"). 36 | - Remove four byte string class and all references to it. 37 | - Rename some of the string functions in Dart API to make them consistent 38 | and better describe the underlying functionality 39 | Dart_NewString => Dart_NewStringFromCString 40 | Dart_NewString8 => Dart_NewStringFromUTF8 41 | Dart_NewString16 => Dart_NewStringFromUTF16 42 | Dart_NewString32 => Dart_NewStringFromUTF32 43 | Dart_NewExternalString8 => Dart_NewExternalUTF8String 44 | Dart_NewExternalString16 => Dart_NewExternalUTF16String 45 | Dart_NewExternalString32 => Dart_NewExternalUTF32String 46 | Dart_StringGet8 => Dart_StringToUTF8 47 | Dart_StringGet16 => Dart_StringToUTF16 48 | Dart_StringToCString => Dart_StringToCString 49 | Dart_IsString8 => Removed 50 | Dart_IsString16 -> Removed 51 | Dart_StringToBytes -> Removed 52 | Dart_StringGet32 -> Removed 53 | -------------------------------------------------------------------------------- /art/gc.rst: -------------------------------------------------------------------------------- 1 | LLVM GC 2 | ############################################################################### 3 | 4 | GCをサポートするための機能 5 | 6 | 7 | LLVM 8 | ******************************************************************************* 9 | 10 | LLVMの場合、Shadow Frameという概念を使って 11 | 12 | module :: 13 | 14 | javaObject = type opaque 15 | %ShadowFrame = type { i32 ; Number of VRegs 16 | , %ShadowFrame* ; Previous frame 17 | , %JavaObject* ; Method object pointer 18 | , i32 ; Line number for stack backtrace 19 | ; [0 x i32] ; VRegs 20 | } 21 | このShadowFrameは、art/rutime/stack.hで定義されているShadowFrameと対応付けられていて、 22 | 23 | 24 | GCの概要 25 | =============================================================================== 26 | 27 | parallel card marking 28 | 29 | concurrent card marking 30 | 31 | allocate 32 | =============================================================================== 33 | 34 | Arena 35 | 36 | Arenaは、backendのコンパイル時にcu.arenaを引数で渡している。 37 | 38 | LIKELYの追加で性能向上 39 | 40 | // Type of allocation for memory tuning. 41 | + enum ArenaAllocKind { 42 | + kAllocMisc, 43 | + kAllocBB, 44 | + kAllocLIR, 45 | + kAllocMIR, 46 | + kAllocDFInfo, 47 | + kAllocGrowableArray, 48 | + kAllocGrowableBitMap, 49 | + kAllocDalvikToSSAMap, 50 | + kAllocDebugInfo, 51 | + kAllocSuccessor, 52 | + kAllocRegAlloc, 53 | + kAllocData, 54 | + kAllocPredecessors, 55 | + kNumAllocKinds 56 | + }; 57 | 58 | 59 | art/compiler/llvm 60 | =============================================================================== 61 | 62 | // Code mappings for deduplication. Deduplication is already done on a pointer basis by the 63 | // compiler driver, so we can simply compare the pointers to find out if things are duplicated. 64 | SafeMap*, uint32_t> code_offsets_; 65 | SafeMap*, uint32_t> vmap_table_offsets_; 66 | SafeMap*, uint32_t> mapping_table_offsets_; 67 | SafeMap*, uint32_t> gc_map_offsets_; 68 | 69 | 70 | interpreterへのtrampoline 71 | utilのtrampolineで定義 72 | 73 | =============================================================================== 74 | 75 | 76 | GC Root visit 77 | ******************************************************************************* 78 | 79 | runtimeから、GCのrootをたどる処理 80 | 81 | llvm側でも定義されている、 82 | GetCurrentShadwoFrame() 83 | ShadowFrameをひたすらたどる 84 | 85 | mirror::ArtMethod* m = shadow_frame->GetMethod() 86 | gc_map = m->GetNativeGcMap(); 87 | 88 | VRegReference 89 | 90 | 91 | 92 | 93 | ShadowFrame 94 | =============================================================================== 95 | art/runtime/stackで定義されている。 96 | 97 | 98 | 99 | =============================================================================== 100 | 101 | template :: 102 | ############################################################################### 103 | ******************************************************************************* 104 | =============================================================================== 105 | 106 | -------------------------------------------------------------------------------- /DartVM/src/out/fibo.java7.asm: -------------------------------------------------------------------------------- 1 | //Fibo.java 2 | class Fibo { 3 | static int fibo(int n) { 4 | if (n < 2) { 5 | //then 6 | return n; 7 | } else { 8 | //else 9 | return fibo(n-1) + fibo(n-2); 10 | } 11 | } 12 | public static void main(String[] args) { 13 | System.out.println(fibo(40)); 14 | } 15 | } 16 | 17 | $ time java -XX:MaxInlineSize=0 -XX:FreqInlineSize=0 -XX:PrintOptoAssembly Fibo 18 | 19 | # 20 | # int ( int ) 21 | # 22 | #r000 ecx : parm 0: int <-- 引数n 23 | # -- Old esp -- Framesize: 32 -- <-- static関数なので、thisはない。 24 | #r045 esp+28: return address <-- 第2引数は、edxに乗ってくる。以降はstack push 25 | #r044 esp+24: saved fp register <-- method callだった場合、ecx=this, edx=arg1 26 | #r043 esp+20: pad2, stack alignment 27 | #r042 esp+16: Fixed slot 0 28 | #r049 esp+12: spill 29 | #r048 esp+ 8: spill 30 | #r047 esp+ 4: spill 31 | #r046 esp+ 0: spill 32 | abababab N1: # B1 <- B6 B9 Freq: 1 33 | abababab 34 | 000 B1: # B5 B2 <- BLOCK HEAD IS JUNK Freq: 1 35 | 000 # stack bang 36 | PUSH EBP # Save EBP 37 | SUB ESP, #24 # Create frame 38 | 39 | 00b MOV EBP,ECX <-- EBP = ECX = n 40 | 00d CMP ECX,#2 <-- if (n < 2) 41 | 010 Jl,s B5 P=0.500013 C=359559.000000 <-- goto then //branchのfreqをカウントしている。 42 | 010 43 | //else 44 | 012 B2: # B7 B3 <- B1 Freq: 0.499987 45 | 012 DEC ECX <-- ECX = (n-1) 46 | 013 CALL,static Fibo::fibo <-- call fibo(n-1) 47 | # Fibo::fibo @ bci:10 L[0]=EBP 48 | # OopMap{off=24} 49 | 018 50 | 018 B3: # B8 B4 <- B2 Freq: 0.499977 51 | # Block is sole successor of call 52 | 018 MOV [ESP + #0],EAX <-- ESP+#0 = fibo(n-1)の返値 53 | 01b MOV ECX,EBP <-- ECX = EBP = n 54 | 01d ADD ECX,#-2 <-- ECX = (n-2) 55 | nop # 3 bytes pad for loops and calls 56 | 023 CALL,static Fibo::fibo <-- call fibo(n-2) 57 | # Fibo::fibo @ bci:16 L[0]=_ STK[0]=esp + #0 58 | # OopMap{off=40} 59 | 028 60 | 028 B4: # B6 <- B3 Freq: 0.499967 61 | # Block is sole successor of call 62 | 028 ADD EAX,[ESP + #0] <-- ret = fibo(n-1) + fibo(n-2) 63 | 02b JMP,s B6 <-- return 64 | 02b 65 | //then 66 | 02d B5: # B6 <- B1 Freq: 0.500013 <-- goto if (n<2) 67 | 02d MOV EAX,ECX <-- EAX = ECX = n 68 | 02d 69 | 02f B6: # N1 <- B5 B4 Freq: 0.99998 70 | 02f ADD ESP,24 # Destroy frame 71 | POPL EBP 72 | TEST PollPage,EAX ! Poll Safepoint 73 | 74 | 039 RET <-- return EAX 75 | 039 76 | 03a B7: # B9 <- B2 Freq: 4.99987e-06 77 | 03a # exception oop is in EAX; no code emitted 78 | 03a MOV ECX,EAX 79 | 03c JMP,s B9 80 | 03c 81 | 03e B8: # B9 <- B3 Freq: 4.99977e-06 82 | 03e # exception oop is in EAX; no code emitted 83 | 03e MOV ECX,EAX 84 | 03e 85 | 040 B9: # N1 <- B7 B8 Freq: 9.99965e-06 86 | 040 ADD ESP,24 # Destroy frame 87 | POPL EBP 88 | 89 | 044 JMP rethrow_stub 90 | 044 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /golang/compiler.rst: -------------------------------------------------------------------------------- 1 | go compiler 2 | ############################################################################### 3 | 4 | キーワードを足がかりに検索してみる。 5 | 6 | largemodel 7 | 8 | peephole 9 | 10 | optimizations 11 | 12 | 13 | 調べるのは 14 | gc cc 6g 15 | 16 | option 17 | ******************************************************************************* 18 | 19 | こんな感じで分岐する 20 | 21 | debug['P'] Peephole 22 | debug['N'] optimize 23 | debug['l'] inlining 24 | 25 | 26 | optimization 27 | =============================================================================== 28 | 29 | grep :: 30 | 31 | cc/lex.c: flagcount("N", "disable optimizations", &debug['N']); 32 | cc/pgen.c: if(!debug['N'] || debug['R'] || debug['P']) 33 | gc/lex.c: flagcount("N", "disable optimizations", &debug['N']); 34 | gc/lex.c: if(!debug['N']) 35 | gc/gen.c: if(debug['N'] && n->esc != EscUnknown) 36 | gc/gen.c: if(!debug['N']) 37 | gc/pgen.c: if(!debug['N'] || debug['R'] || debug['P']) { 38 | gc/typecheck.c: if(debug['N'] && !(top & Eindir) && !n->etype) 39 | gc/typecheck.c: if(debug['N']) 40 | 41 | 42 | gen.c :: 43 | 44 | EscUnknown fatal("without escape analysis, only PAUTO's should have esc: %N", n); 45 | 46 | n->esc = EscHeap 47 | 48 | エスケープ解析をAST上のNodeのTreeを辿り(walk)ながら行っている。 49 | 50 | go.h :: 51 | 52 | EscUnknown 53 | EscHeap esc(h) 54 | EscScope esc(s) 55 | EscNone esc(no) 56 | EscReturn 57 | EscNever esc(N) 58 | EscBits 59 | EscMask 60 | 61 | visit 62 | analyze 63 | esctag 64 | escflood 65 | escwalk 66 | 67 | escloopdepth 68 | 69 | walk.c 70 | newしている箇所(Node)において、 71 | escNoneの場合callnewの代わりに、stackにtempを確保する 72 | 73 | 参照型のsliceも対象っぽい。 74 | 75 | 76 | gc/pgen.c :: 77 | 78 | regopt() //peephole or register optimizer 79 | nilopt() 80 | 81 | expandchecks() 82 | 83 | gc/typecheck.c :: 84 | 85 | addrescapes() //これはescapeすると強制判定 86 | 87 | cc/pgen.c :: 88 | 89 | regopt() 90 | 91 | gc/lex 92 | =============================================================================== 93 | 94 | main :: 95 | 96 | Phase 1: 97 | Phase 2: variable assignments, to interface assm 98 | Phase 3: type check function bodies 99 | Phase 4: Inlining 100 | typecheckinl() 101 | caninl() 102 | inlcalls() 103 | Phase 5: Escape analysis 104 | escapes() 105 | movelarge() 106 | if n->class == PAUTO and type != T nad width > MaxStacVarSize 107 | addrescapes(n) 108 | 109 | Phase 6: Compile top level 110 | funccompile() 111 | fninit(xtop) 112 | 113 | Phase 7: Check external declarations 114 | typecheck 115 | 116 | dumpobj() 117 | 118 | funccompile(Node *, isclosure) 119 | =============================================================================== 120 | 121 | 必要なstack sizeの見積りを行ってからcompile 122 | 123 | compile(Node * ) //pgen 124 | 125 | 126 | gen NodeがTree構造 127 | pgen レジスタ割付してアセンブリ 128 | portable code generator 129 | 130 | 131 | =============================================================================== 132 | 133 | template :: 134 | ############################################################################### 135 | ******************************************************************************* 136 | =============================================================================== 137 | 138 | -------------------------------------------------------------------------------- /art/optimize.rst: -------------------------------------------------------------------------------- 1 | Optimize 2 | ############################################################################### 3 | 4 | commit 818f2107e6d2d9e80faac8ae8c92faffa83cbd11 5 | Author: Nicolas Geoffray 6 | Date: Tue Feb 18 16:43:35 2014 +0000 7 | 8 | Re-apply: Initial check-in of an optimizing compiler. 9 | 10 | The classes and the names are very much inspired by V8/Dart. 11 | It currently only supports the RETURN_VOID dex instruction, 12 | and there is a pretty printer to check if the building of the 13 | graph is correct. 14 | 15 | Change-Id: I28e125dfee86ae6ec9b3fec6aa1859523b92a893 16 | 17 | compiler/optimizing 18 | =============================================================================== 19 | 20 | builder.h 21 | 22 | HGraph これはV8由来の名前っぽい。 23 | 24 | HBasicBlock 25 | 26 | HInstruction 27 | 28 | Exit 29 | Goto 30 | ReturnVoid 31 | 32 | 33 | Graphは、 34 | code_ptrを参照して、 35 | AnalyzeDexInstruction 36 | 37 | DexをHGraphに変換するのか。 38 | 39 | GenerateFrameEntry 40 | GenerateFrameExit 41 | 42 | optimizeはどこから呼ばれる。 43 | =============================================================================== 44 | 45 | 2014/03頭の段階では、どこからも呼び出しはないっぽいな。 46 | 47 | ARTはcompiler/optimizing 48 | ってディレクトリを追加して、ファイルを整理。 49 | またHGraphってを追加している。これはV8由来CrankshaftのHIRと名前が一致。 50 | まだ呼び出しはどこにもない。 51 | 52 | code generatorが追加されて、V8 Crankshaftっぽくなってきた。 53 | 54 | 55 | OptimizingCompiler::TryCompile 56 | HGraphBuilder::BuildGraphが起点 57 | 58 | =============================================================================== 59 | =============================================================================== 60 | 61 | OptimizingCompiler 62 | ******************************************************************************* 63 | 64 | compiler.ccでコンパイラを切り替えている。 65 | 66 | Compiler::Create() 67 | 68 | QuickCompiler 69 | 70 | OptimizingCompiler 71 | 72 | LLVMCompiler //Portable 73 | 74 | OptimizingCompiler::TryCompile 75 | =============================================================================== 76 | 77 | flow :: 78 | 79 | DexCompilationUnit() 80 | 81 | HGraphBuolder builder.BuildGraph() 82 | HBasicBlockを生成 83 | ComputeBranchTargets() 84 | 85 | driver.GetInstructionSet() 86 | CodeGenerator::Create() 87 | 88 | CodeVectorAllocator allocator; 89 | codegen->Compile(&allocator); 90 | GenerateFrameEntry() 91 | CompileBlock() 92 | Allocate() 93 | MemoryRegion code 94 | 95 | codegen->BuildMappingTAble 96 | codegen->BuildVMapTable 97 | codegen->BuildNativeGCMap 98 | 99 | //ここにあるのはおかしい。メインパスに入ってないだけか? 100 | graph->BuildDominatorTree() 101 | graph->TransformToSSA() 102 | 103 | return new CompiledMethod() 104 | 105 | 106 | 最適化? 107 | =============================================================================== 108 | 109 | test :: 110 | 111 | HGraphBuilder builder BuildGraph() 112 | BuildDominatorTree() 113 | TransformToSSA() 114 | SimplifyCFG() 115 | ssa_builder.BuildSsa() 116 | 117 | なんもやってない。 118 | 119 | =============================================================================== 120 | =============================================================================== 121 | =============================================================================== 122 | 123 | template :: 124 | ############################################################################### 125 | ******************************************************************************* 126 | =============================================================================== 127 | 128 | -------------------------------------------------------------------------------- /DartVM/src/start.rst: -------------------------------------------------------------------------------- 1 | dart startup 2 | ############################################################################### 3 | 4 | dartコマンドはmain 5 | 6 | bin/main 7 | ******************************************************************************* 8 | 9 | bin/main.cc :: 10 | 11 | Dart_Initialize() 12 | 13 | Dart_Isolate isolate = CreateIsolateAndSetupHelper() 14 | 15 | Dart_CreateIsolate() <-- init snapshot buffer 16 | Dart::InitializeIsolate(snapshot,) 17 | LoadAndCheckLibrary() 18 | LoadScript() 19 | 20 | Dart_ExitIsolate() 21 | Dart_IsolateMakeRunnable() //これで起動。 22 | iso->MakeRunnable() 23 | 24 | Dart_EnterIsolate(isolate) 25 | Dart_Invoke() 26 | Dart_RunLoop() 27 | 28 | // snapshot_buffer points to a snapshot if we link in a snapshot otherwise 29 | // it is initialized to NULL. 30 | extern const uint8_t* snapshot_buffer; 31 | bin/snapshot_inc.cc 32 | 33 | in building obj/gen/snapshot_gen.cc 34 | 35 | bin/snapshot_in.cc <-- make 36 | 37 | generate_snapshot_file.host.mk 38 | runtime/tool/create_snapshot_file.py input output inputbin 39 | input_bin = snapshot_gen.bin 40 | 41 | vm/dart_api_impl.cc :: 42 | 43 | Dart_Initialize(snapshot) 44 | Dart::InitOnce() 45 | OS::InitOnce() 46 | VirtualMemory::InitOnce() 47 | Isolate::InitOnce() 48 | PortMap::IniOnce() 49 | FreeListElement::InitOnce() 50 | Api::InitOnce() 51 | CodeObservers::InitOnce() 52 | ThreadPool() 53 | ObjectStore::Init() 54 | 55 | Dart_CreateIsolate() 56 | Dart::CreateIsolate() 57 | Isoalte::Init() 58 | Dart::InitializeIsolate() 59 | 60 | =============================================================================== 61 | =============================================================================== 62 | =============================================================================== 63 | 64 | 65 | Isolate::Init() 66 | new Isolate() 67 | main_port_ 68 | heap_ 69 | object_store_ 70 | top_context_ 71 | api_state_ 72 | stub_code_ 73 | 74 | Dart::InitializeIsolate() 75 | or Obect::Init(Isolate) <-- dart_no_snapshot 76 | Object::InitFromSnapshot(isolate) <-- dart 77 | // before print_bootstrap 78 | SnapshotReader reader(,,, kFull, 79 | reader.ReadFullSnapshot() 80 | 81 | Isolate initializetion 11455 - 81173 micros. 82 | Script Loading 50 -> 45183 micros. 83 | Bootstrap of core classes 28 - 81173 micros. 84 | object::init 85 | 86 | --- 87 | TIMERSCOPE 88 | 89 | time_all: false (Time all functionality) 90 | time_bootstrap: false (time_bootstrap) 91 | time_compilation: false (time_compilation) 92 | time_creating_snapshot: false (time_creating_snapshot) 93 | time_isolate_initialization: false (time_isolate_initialization) 94 | time_script_loading: false (time_script_loading) 95 | time_total_runtime: false (time_total_runtime) 96 | trace_runtime_calls: false (Trace runtime calls) 97 | trace_type_check_elimination: false (Trace type check elimination at compile time.) 98 | trace_type_checks: false (Trace runtime type checks.) 99 | worker_timeout_millis: 5000 (Free workers when they have been idle for this amount of time.) 100 | 101 | 102 | 103 | 104 | bin/gen_snapshot.cc 105 | LoadSnapshotCreationScript(app_script_name) 106 | CreateAndWriteSnapshot(); 107 | Dart_CreateSnapshot() 108 | object_store()-set_root_library() 109 | FullSnapshotWrite() 110 | 111 | core -> RawLibrary 112 | RawScript 113 | RawString 114 | RawTokenStream 115 | 116 | 117 | TokenStream 118 | -------------------------------------------------------------------------------- /OpenJDK/wb.rst: -------------------------------------------------------------------------------- 1 | Write Barrier 2 | ############################################################################### 3 | 4 | twitter :: 5 | 6 | 世代別GCのwrite burrierのコストというか、オーバーヘッドってどのくらいなんだろうか。。 7 | アーキに寄るでしょう。hotspotの場合putfieldされる型は不明なので、 8 | writeburrierで一度チェックが必要ということですか? 9 | hotspotの場合、nativeはgcの対象外でしょうし、nativeの配列もwb対象外ですよね。 10 | 全部objectだと、おっとだれかk 11 | Hotspot JVMのような古典的なライトバリアはa.fied=bのようなputfieldなどが 12 | 実行されたらそれがbがNew領域だろうがOld領域だろうが気にせずにバイトマップに書き込んで 13 | それが速かったわけです。 14 | でも同じやり方がNUMA的にメモリのアクセス速度に遠近ができたアーキで 15 | 正しいかと言われるとそうでもないはず。 16 | 今ならa.filed=bのaがOldでbがNewである条件を判定してからSETccあたりで書いたほうが速いかもしれません。 17 | Hotspotはputfieldされる型がprimitive型か参照型かは 18 | 命令のfield descriptorを見れば決定できるのでそこでの判断は不要ですよ。 19 | 問題は新世代のオブジェクトの参照が旧世代に持ち出されたところでWBしなくてはならないけど、 20 | その条件を真面目に適用するとputfieldの本来の処理より副作用のコードの方が多くなって 21 | 性能が悪かったのですが、これも時代が変わると処理も変わりそうです。 22 | 思い出したから呟いておく。 23 | x86のCMOVccにはメモリへの1バイト書き込みと、 24 | 定数値をレジスタに載せるCMOVcc reg,immがないのが許せん。 25 | あとCADDccぐらいは用意しやがれ。 26 | つ Barriers Reconsidered, Friendlier Still! 27 | http://users.cecs.anu.edu.au/~steveb/downloads/pdf/barrier-ismm-2012.pdf 真面目に読んでないですが。 28 | 29 | share 30 | =============================================================================== 31 | 32 | #include "memory/barrierSet.hpp" 33 | #include "memory/cardTableModRefBS.hpp" 34 | #include "memory/barrierSet.inline" 35 | 36 | memory/cardTableRS 37 | 38 | read_ref_barrier 39 | read_prim_barrier 40 | write_ref_pre_barrier 41 | write_ref_barrier 42 | write_prim_barrier 43 | 44 | 45 | 46 | SharedRuntime::g1_wb_post 47 | SharedRuntime::g1_wb_pre 48 | 49 | satbとは 50 | Snapshot at the beginning 51 | 52 | SATB 53 | 54 | Thread-local log for SATB barrier. 55 | Thread-local log for dirty cards. 56 | 57 | wbの挿入箇所 58 | =============================================================================== 59 | 60 | putfield 61 | 62 | putstatic 63 | 64 | aastore 65 | 66 | それぞれがどの中間表現になるのか。 67 | 68 | c1 69 | =============================================================================== 70 | g1版のpre_barrier post_barrier 71 | 72 | slow版 73 | 74 | pre_barrier 75 | 76 | post_barrier 77 | 78 | needs_write_barrier 79 | 80 | G1STABCardTableModRef 81 | 82 | CardTableModRef 83 | 84 | opto 85 | =============================================================================== 86 | 87 | c2_globals.hpp insert memory barrier after arraycopy call 88 | 89 | g1_write_barrier_pre 90 | g1_write_barrier_post 91 | 92 | pre_barrier 93 | post_barrier 94 | 95 | need_read_barrier 96 | 97 | Matcher 98 | 99 | post_store_load_barrier 100 | 101 | ad ??? 102 | 103 | cpu/x86 104 | =============================================================================== 105 | 106 | assembler_x86.cpp 107 | 108 | MacroAssembler::g1_write_barrier_pre() 109 | 110 | MacroAssembler::g1_write_barrier_post() 111 | 112 | 113 | gen_write_ref_array_pre_barrier() 114 | g1の場合のみ使用する。 115 | BarrierSet::static_write_ref_array_pre 116 | 117 | gen_write_ref_array_post_barrier() 118 | g1の場合のみ使用する。 119 | BarrierSet::static_write_ref_array_post 120 | 121 | CardTableの場合 122 | decrement 123 | 124 | ModRefの場合 125 | 何もしない 126 | 127 | ad 128 | =============================================================================== 129 | 130 | member_acquire 131 | memoby_storestore 132 | 133 | 関係ないかも 134 | 135 | 136 | =============================================================================== 137 | =============================================================================== 138 | =============================================================================== 139 | -------------------------------------------------------------------------------- /DartVM/src/regalloc.rst: -------------------------------------------------------------------------------- 1 | 2 | ############################################################################### 3 | 4 | 5 | 6 | ******************************************************************************* 7 | 8 | ssa形式のirは、番号付けされている。 9 | BitVectorで省エネ 10 | 11 | analyze liveness 12 | =============================================================================== 13 | 14 | AnalyzeLiveness() 15 | live_out初期化 16 | kill初期化 17 | live_in初期化 18 | 19 | ComputeInitialSets() 20 | blockを走査 i 21 | if IsJoinEntry() 22 | predのphiを収集して、 23 | kill mark 24 | 25 | 自信のphiを拾って、 26 | phiをひろって、 27 | live_out mark 28 | instを走査 it 29 | if (!kill) live_in 30 | 31 | ComputeLiveInAddLiveOutSets() 32 | block走査 33 | UpdateLiveOut(block) 34 | blockのlive_outの集合に、block->succ()のlive_inを集合加算 35 | updateLiveIn(block) 36 | live_in->KillAndAdd(kill, live_out) 37 | if () 38 | changed = true 39 | 40 | build live ranges 41 | =============================================================================== 42 | 43 | BuildLiveRanges() 44 | blockを走査 45 | range->AddUseIntervals(GetLiveRange()) 46 | if IsParallelMove() 47 | 48 | Locationする 49 | 50 | 51 | allocate cpu registers 52 | =============================================================================== 53 | 54 | AllocateCPURegisters() 55 | while(unallocated) 56 | AdvanceActiveIntervals() 57 | FinalizeInterval() 58 | AllocateFreeRegister() 59 | LookAhadForHint() 60 | AssignFreeRegister() 61 | 62 | 63 | AdvanceActiveIntervals() 64 | 65 | 66 | =============================================================================== 67 | =============================================================================== 68 | 69 | サブセクション 70 | ------------------------------------------------------------------------------- 71 | 72 | =============================================================================== 73 | =============================================================================== 74 | =============================================================================== 75 | ------------------------------------------------------------------------------- 76 | ------------------------------------------------------------------------------- 77 | ------------------------------------------------------------------------------- 78 | 79 | 80 | ------------------------------------------------------------------------------- 81 | ------------------------------------------------------------------------------- 82 | ------------------------------------------------------------------------------- 83 | ------------------------------------------------------------------------------- 84 | 85 | ------------------------------------------------------------------------------- 86 | 87 | ------------------------------------------------------------------------------- 88 | 89 | 90 | 91 | 92 | =============================================================================== 93 | 94 | 95 | ------------------------------------------------------------------------------- 96 | ------------------------------------------------------------------------------- 97 | ------------------------------------------------------------------------------- 98 | 99 | 100 | 101 | 102 | 103 | .. image:: xxx.png 104 | 105 | .. literalinclude:: xxx.js 106 | 107 | .. graphviz:: 108 | 109 | 110 | xxx :: 111 | 112 | xxx 113 | 114 | .. code-block:: python 115 | :linenos: 116 | 117 | .. literalinclude:: src/test.py 118 | 119 | :language: python 120 | :linenos: 121 | 122 | 123 | -------------------------------------------------------------------------------- /golang/cmd.rst: -------------------------------------------------------------------------------- 1 | goコマンドの各種オプションについて 2 | ############################################################################### 3 | 4 | 適当に 5 | ******************************************************************************* 6 | 7 | go env 8 | =============================================================================== 9 | 10 | :: 11 | 12 | GOARCH="amd64" 13 | GOBIN="" 14 | GOCHAR="6" 15 | GOEXE="" 16 | GOHOSTARCH="amd64" 17 | GOHOSTOS="linux" 18 | GOOS="linux" 19 | GOPATH="/home/elise/share/golang" 20 | GORACE="" 21 | GOROOT="/home/elise/language/golang/go" 22 | GOTOOLDIR="/home/elise/language/golang/go/pkg/tool/linux_amd64" 23 | TERM="dumb" 24 | CC="gcc" 25 | GOGCCFLAGS="-g -O2 -fPIC -m64 -pthread" 26 | CXX="g++" 27 | CGO_ENABLED="1" 28 | 29 | 30 | go build 31 | =============================================================================== 32 | 33 | -gcflags '-N -l' 最適化されなくなるため、バイナリが大きくなるが、 34 | gdb debuggin時の変数がたくさん見える 35 | 36 | inline展開された一時変数はdebugerから参照できなくなるため、 37 | 上記は最適化とinline展開をコンパイラに抑止させる。 38 | 39 | go build -gcflags --help 40 | =============================================================================== 41 | 42 | --helpが必要 43 | 44 | go build -gcflags --help :: 45 | 46 | usage: 6g [options] file.go... 47 | -+ compiling runtime 48 | -% debug non-static initializers 49 | -A for bootstrapping, allow 'any' type 50 | -B disable bounds checking 51 | -D path 52 | set relative path for local imports 53 | -E debug symbol export 54 | -I dir 55 | add dir to import search path 56 | -K debug missing line numbers 57 | -L use full (long) path in error messages 58 | -M debug move generation 59 | -N disable optimizations 60 | -P debug peephole optimizer 61 | -R debug register optimizer 62 | -S print assembly listing 63 | -V print compiler version 64 | -W debug parse tree after type checking 65 | -complete compiling complete package (no C or assembly) 66 | -d list 67 | print debug information about items in list 68 | -e no limit on number of errors reported 69 | -f debug stack frames 70 | -g debug code generation 71 | -h halt on error 72 | -i debug line number stack 73 | -installsuffix pkg directory suffix 74 | -j debug runtime-initialized variables 75 | -l disable inlining 76 | -m print optimization decisions 77 | -o obj 78 | set output file 79 | -p path 80 | set expected package import path 81 | -r debug generated wrappers 82 | -race enable race detector 83 | -s warn about composite literals that can be simplified 84 | -u reject unsafe code 85 | -v increase debug verbosity 86 | -w debug type checking 87 | -x debug lexer 88 | -y debug declarations in canned imports (with -d) 89 | -largemodel generate code that assumes a large memory model 90 | 91 | デバッグ時は 92 | -N -l 93 | 94 | 最適化時は 95 | 96 | bounds checking 97 | move generation 98 | optimization 99 | peephole 100 | register 101 | inlining 102 | largemodel 103 | 104 | escape解析を制御するオプションが見当たらないな。。 105 | 106 | デバッグ用のオプション 107 | =============================================================================== 108 | 109 | -gcflagsに-Sをつけるとアセンブリが出力される。 110 | 111 | =============================================================================== 112 | =============================================================================== 113 | =============================================================================== 114 | template :: 115 | ############################################################################### 116 | ******************************************************************************* 117 | =============================================================================== 118 | 119 | -------------------------------------------------------------------------------- /DartVM/src/thread.rst: -------------------------------------------------------------------------------- 1 | thread 2 | ############################################################################### 3 | 4 | threadは主にthread_poolで管理している。 5 | 6 | thread_poolは、dart.ccで定義されており、グローバル変数である。 7 | 8 | :: 9 | 10 | therad_pool = new ThreadPool() // dart.cc 11 | 12 | dart.cc::Dart::InitOnce()で初期化する。 13 | 14 | thread_poolは下記を定義している。 15 | 16 | class ThreadPool, class ThreadPool::Task, class ThreadPool::Worker 17 | 18 | thread_pool :: 19 | 20 | ThreadPool::Run(Task*) 21 | worker->SetTask(task); 22 | worker->StartThread(); 23 | Thread::Start(&Worker::Main 24 | 25 | runtime/platformディレクトリは、os依存の処理を定義している。 26 | 27 | os依存の処理は、Thread, Mutex, Monitor等である。 28 | 29 | # class Thread 30 | ## Start(function, parameters) <-- これが一番使う 31 | ## DeleteThreadLocal 32 | ## GetThreadLocal 33 | ## SetThreadLocal 34 | 35 | #class Mutex 36 | ## Lock() 37 | ## TryLock() 38 | ## Unlock() 39 | 40 | #class Monitor 41 | ## Enter() 42 | ## Exit() 43 | 44 | 45 | ThredPool::Run() Taskの一覧 46 | ******************************************************************************* 47 | 48 | runtime/vm :: 49 | 50 | //message_handler 51 | MesssageHandlerTask : public ThreadPool::Task 52 | 53 | Isolate::Run() 54 | message_handler()->Run() 55 | 56 | //native_api_impl.cc native_message_handler 57 | Dart_NewNativePort() 58 | nmh = new NativeMessageHandler() 59 | nmh->Run(Dart::therad_pool() 60 | 61 | 62 | runtime/lib/isolate.cc :: 63 | 64 | IsolateSpawnState() //isolate.cc 65 | Isolate* child_isolate = reinterpret_cast( 66 | (callback)(state->script_url(), 67 | state->function_name(), 68 | init_data, 69 | error)); 70 | 71 | state->isolate->Run() //runtime/vmのIsoalte::Run() 72 | void Isolate::Run() { 73 | message_handler()->Run(Dart::thread_pool(), 74 | RunIsolate, 75 | ShutdownIsolate, 76 | reinterpret_cast(this)); 77 | } 78 | 79 | 80 | 81 | state->isolate()->Run()で新規のスレッドを生成する。 82 | 83 | 内部では、message_handlerを別スレッドで生成し、Isolateの初期化およびStart処理を 84 | callback登録して実行する。 85 | 86 | isolateとmessagehandlerで2threadじゃなくて、 87 | messagehandlerで立てる1threadだけ 88 | 89 | threadはmessagehandlerで立てて、callbackする 90 | 91 | 92 | runtime/bin :: 93 | 94 | dbg_connection_android.cc: int result = dart::Thread::Start(&DebuggerConnectionImpl::Handler, 0); 95 | dbg_connection_linux.cc: int result = dart::Thread::Start(&DebuggerConnectionImpl::Handler, 0); 96 | dbg_connection_macos.cc: int result = dart::Thread::Start(&DebuggerConnectionImpl::Handler, 0); 97 | dbg_connection_win.cc: int result = dart::Thread::Start(&DebuggerConnectionImpl::ThreadEntry, 0); 98 | eventhandler_android.cc: int result = dart::Thread::Start(&EventHandlerImplementation::Poll, 99 | eventhandler_linux.cc: int result = dart::Thread::Start(&EventHandlerImplementation::Poll, 100 | eventhandler_macos.cc: dart::Thread::Start(&EventHandlerImplementation::EventHandlerEntry, 101 | eventhandler_win.cc: int result = dart::Thread::Start(EventHandlerEntry, 102 | file_system_watcher_macos.cc: Thread::Start(Run, reinterpret_cast(this)); 103 | process_android.cc: int result = dart::Thread::Start(ExitCodeHandlerEntry, 0); 104 | process_linux.cc: int result = dart::Thread::Start(ExitCodeHandlerEntry, 0); 105 | process_macos.cc: int result = dart::Thread::Start(ExitCodeHandlerEntry, 0); 106 | vmservice_impl.cc: dart::Thread::Start(ThreadMain, server_port); 107 | 108 | 109 | =============================================================================== 110 | =============================================================================== 111 | =============================================================================== 112 | -------------------------------------------------------------------------------- /DartVM/src/advent20121208.rst: -------------------------------------------------------------------------------- 1 | Dart VM Advent Calendar 2012 12/08 2 | ############################################################################### 3 | 4 | Dart VMと他VMの比較 5 | =============================================================================== 6 | Dart VMと、他のVMやコンパイラが出力したアセンブラを比較してみようと思います。。 7 | 8 | - LLVM(clang3.2 trunk) 9 | - Dart VM 10 | - V8 11 | - JVM(java7 Hotspot) 12 | 13 | とはいえ、比較対象はfibonacchi関数なので、実アプリケーションによるベンチマークではないです。 14 | 15 | マイクロベンチマークでこの程度かという認識でお願いします。 16 | 17 | Time Fibo(40) 18 | =============================================================================== 19 | fibo(40)の処理時間です。参考までに。 20 | 21 | ubuntu12(ia32) corei7 2600です。 22 | 23 | clang32$ time fibo.clang32.O3.out :: 24 | 25 | ret=102334155 26 | real 0m0.620s 27 | user 0m0.616s 28 | sys 0m0.000s 29 | 30 | V8$ time shell fibo.js :: 31 | 32 | ret=102334155 33 | 1401 millis 34 | real 0m1.401s 35 | user 0m1.404s 36 | sys 0m0.000s 37 | 38 | java7$ time java Fibo :: 39 | 40 | ret=102334155 41 | 420 millis 42 | real 0m0.466s 43 | user 0m0.452s 44 | sys 0m0.016s 45 | 46 | なぜかClangよりも速い。。アセンブラを参照してみたら、再帰関数Fiboをinline展開していました。 47 | 48 | そのため、以下のInline展開を抑止した版と比較します。 49 | 50 | inline展開を抑止した場合、VM起動時のオーバーヘッドを除くと、ほぼclangと同等の速度ですね。 51 | 52 | $ time java -XX:MaxInlineSize=0 -XX:FreqInlineSize=0 Fibo :: 53 | 54 | ret = 102334155 55 | 602 millis 56 | real 0m0.663s 57 | user 0m0.628s 58 | sys 0m0.036s 59 | 60 | 61 | dart$ time dart --time-all fibo.dart :: 62 | 63 | ret = 102334155 64 | 897 millis 65 | Script Loading : 93 micros. 66 | Snapshot Creation : 0 micros. 67 | Isolate initialization : 11019 micros. 68 | Function compilation : 11742 micros. 69 | Bootstrap of core classes : 28 micros. 70 | Total runtime for isolate : 909578 micros. 71 | real 0m0.924s 72 | user 0m0.920s 73 | sys 0m0.000s 74 | 75 | 前回の最後に紹介したデータです。 76 | 77 | clangのアセンブラ 78 | =============================================================================== 79 | 80 | .. literalinclude:: out/fibo.clang32.asm 81 | 82 | シンプルで素直なアセンブラを出力します。これが比較のベースですね。 83 | 84 | GCCでない理由は、VMの名前が入っていないからではなく、 85 | GCCはfiboに対して最適化を行ってしまうため、比較対象にしていません。 86 | 87 | .. note :: 88 | 89 | GCCv4.6は、fiboをループに変換し、そのループからfiboを再帰呼び出しする形に変換します。 90 | 91 | gccv4.6でfibo(40)をコンパイルすると、400msでした。 92 | 93 | fiboをif (n==0) ... else if (n==1) ... else の形式に変換すれば、200msになります。 94 | 95 | V8のアセンブラ 96 | =============================================================================== 97 | 98 | .. literalinclude:: out/fibo.js.asm 99 | 100 | 頭痛くなってくる。。 101 | 102 | Dart VMとV8を比較すると、 103 | 104 | - どちらも、StackOverflowCheckがある。 105 | - V8は、Smi型からuntagして、各種演算を行う。 106 | - V8は、untagした値をsmitagする際に、overflowcheckを行う。 107 | - Dart VMは、Smi型のまま各種演算を行っている。 108 | - V8は、callerのproeprty call checkを行っている。 109 | 110 | あと予想として、Dart VMは中間表現のままRegister割付を行うため、無駄なレジスタ操作が発生していそう。。 111 | 112 | V8はlithiumという低水準中間表現でレジスタ割付を行うため、無駄なレジスタ操作やスピルは少ないんじゃないかな。 113 | 114 | どちらもLinear Scan Register Allocationだけど、レジスタプレッシャが大きい処理やループで傾向を比較すると分かるかもしれない。 115 | 116 | Java7(inline展開抑止版)のアセンブラ 117 | =============================================================================== 118 | 119 | .. literalinclude:: out/fibo.java7.asm 120 | 121 | Dart VMとJava7(HotSpot)を比較すると、 122 | 123 | - Dart VMの引数は、すべてスタック渡し、HotSpotの引数は、第2引き数までレジスタ渡し。fastcall風。 124 | - HotSpotにスタックオーバーフローチェックはない? 125 | - HotSpotは、int型がpremitive型なので、そのままレジスタで扱える。これはHeapObjectの扱いとGCのオーバーヘッドとメモリ使用量の差を比較しないとなんともいえないけど。。 126 | - HotSpotは、fiboみたいな単純な関数では、DeoptimizeFrameは存在しない。クラスを使用したり、仮想関数呼び出しが必要かな。 127 | - HotSpotは、RETの直前に、TEST PollPage,EAX ! Poll Safepointが存在する。GC用のpollingポイントだと思うけど。。謎。 128 | - Dart VMにはpollingポイントの埋め込みがないけど、別途Stackmapを作成して管理しているから問題ないのかな。その辺はまだよくっってない。 129 | 130 | Dart VMのアセンブラ 131 | =============================================================================== 132 | 133 | .. literalinclude:: out/fibo.fibo.aasm 134 | 135 | まとめ 136 | =============================================================================== 137 | (1) HotSpotやばい。C言語と性能競争の話題がでるだけはある。 138 | (2) V8はもうちょっとなんとかならないんですかね。。 139 | -------------------------------------------------------------------------------- /DartVM/src/advent20121202.rst: -------------------------------------------------------------------------------- 1 | Dart VM Advent Calendar 2012 12/02 2 | ############################################################################### 3 | 4 | Dart VMのビルド方法 5 | =============================================================================== 6 | ビルド方法を紹介します。 7 | 8 | Linuxを前提に話を進めます。 私の環境は、Ubuntu12 ia32です。 9 | 10 | Dart VMのソースコード取得 11 | =============================================================================== 12 | ソースコードの取得方法は、以下のURLでも紹介しています。gitでの取得方法は、URLを参照ください。 13 | 14 | http://code.google.com/p/dart/wiki/GettingTheSource 15 | 16 | Dart VMのソースコードは、gclientを使ってダウンロードします。 17 | 18 | Dartの関連すべてをダウンロードしてくるので、結構時間がかかります。 19 | 20 | gclientの取得方法:: 21 | 22 | $ svn co http://src.chromium.org/svn/trunk/tools/depot_tools 23 | $ ls 24 | depot_tools 25 | 26 | Dartのソースコード取得&更新方法:: 27 | 28 | $ export PATH=/home/elise/language/dart/depot_tools:$PATH 29 | $ gclient config http://dart.googlecode.com/svn/branches/bleeding_edge/deps/all.deps 30 | $ gclient sync 31 | $ ls 32 | dart 33 | 34 | ソースコードの取得先は2ヶ所あります。trunkとbleeding_edgeです。:: 35 | 36 | gclient config http://dart.googlecode.com/svn/trunk/deps/all.deps 37 | gclient config http://dart.googlecode.com/svn/branches/bleeding_edge/deps/all.deps 38 | 39 | trunkは、テストでALLOKになった単位で、bleeding_edgeからmergeして管理しているようです。 40 | 41 | bleeding_edgeは毎日更新されるリポジトリで、以下のbuildbotで様子が見れます。 42 | 43 | http://build.chromium.org/p/client.dart/console 44 | 45 | 46 | Dart VMのビルド 47 | =============================================================================== 48 | 49 | ビルド方法は以下のURLで紹介しています。デフォルトではDebugビルドです。 50 | 51 | http://code.google.com/p/dart/wiki/Building 52 | 53 | ビルドは、build.pyというスクリプトを使用します。 54 | 55 | Dartのパッケージすべてをビルドする場合 :: 56 | 57 | $ ls 58 | dart 59 | $ cd dart 60 | $ ./tools/build.py --mode=release --arch=ia32 61 | $ ls out 62 | ReleaseIA32 63 | 64 | Dart VMのみをビルドする場合 :: 65 | 66 | $ ls 67 | dart 68 | $ cd dart/runtime 69 | $ ../tools/build.py --mode=release --arch=ia32 70 | $ ls out 71 | ReleaseIA32 72 | $ ls out/ReleaseIA32 73 | dart 74 | dart_no_snapshot 75 | gen_snapshot 76 | packages 77 | process_test 78 | run_vm_tests 79 | 80 | オプションの指定で切り替えられます。 archの指定は、なくてもいいかも。 81 | 82 | デフォルトではDebugビルドなので、Release版の場合、release指定が必須です。 83 | 84 | ビルドが終わったら、適当にパスを通しておくことをおすすめします。 :: 85 | 86 | $ export PATH=xxx/dart/runtime/out/ReleaseIA32 87 | $ export PATH=xxx/dart/out/ReleaseIA32 88 | $ export PATH=xxx/dart/out/ReleaseIA32/dart-sdk/bin 89 | 90 | dart-sdk、たぶんよく配布されるDartSDKと呼ばれるものだとおもいます。 91 | 92 | その中には、dart_analyzer、dartdoc, pubが入っています。 93 | 94 | build.py オプションの一覧 :: 95 | 96 | $ ./build.py --help 97 | Usage: build.py [options] 98 | 99 | Options: 100 | -h, --help show this help message and exit 101 | -m [all,debug,release], --mode=[all,debug,release] 102 | Build variants (comma-separated). 103 | -v, --verbose Verbose output. 104 | -a [all,ia32,x64,simarm,arm], --arch=[all,ia32,x64,simarm,arm] 105 | Target architectures (comma-separated). 106 | --os=[all,host,android] 107 | Target OSs (comma-separated). 108 | -j 8 The number of parallel jobs to run. 109 | --devenv=DEVENV Path containing devenv.com on Windows 110 | --executable=EXECUTABLE 111 | Name of the devenv.com/msbuild executable on Windows 112 | (varies for different versions of Visual Studio) 113 | 114 | 115 | その他 116 | =============================================================================== 117 | ビルド環境は、gypで管理されています。 118 | 119 | gypは、Linuxのみなので、他のプラットフォームでのビルドは不明。 120 | 121 | Dart自体は、ia32 or x64の、Linux, MacOS, Windowsに対応しています。 122 | 123 | また、おもしろいことに、Linux ia32環境から、android向けにクロスビルドすることもできます。 124 | 125 | 以下のURLでクロスビルド方法を解説しています。 126 | 127 | http://code.google.com/p/dart/wiki/Android 128 | 129 | また、私がAndroid on DartVMを試したときのことも紹介します。 130 | 131 | http://www.slideshare.net/nothingcosmos/yokohamapf25-nothingcosmos 132 | 133 | -------------------------------------------------------------------------------- /erlang/reference.rst: -------------------------------------------------------------------------------- 1 | References 2 | ############################################################################### 3 | 4 | http://ftp.sunet.se/pub/lang/erlang/white_paper.html 5 | =============================================================================== 6 | 7 | http://ll2.ai.mit.edu/talks/armstrong.pdf 8 | =============================================================================== 9 | 10 | * Process creation times 11 | 12 | jvm csharpは、1000p で終了 13 | 14 | 100-200ms / process 15 | 16 | erlang 17 | 18 | 2000 - 30,000 process 19 | 20 | 3-5 microseconds 21 | 22 | * Message passing times 23 | 24 | jvm csharp 25 | 26 | 30microsecond 27 | 28 | erlang 29 | 0.5 - 1 microsecond 30 | 31 | * scalable process 32 | 33 | 重要な点として、 34 | 35 | # プロセス生成のレイテンシが低い 36 | # メッセージ送受信のレイテンシが低い 37 | 38 | 上記がプロセス数に対してうまくscaleする。プロセス数は30,000くらいまでいける。 39 | 40 | JVMやCsharpは1000~2000 processまで 41 | 42 | プロセスのscaleに必要なこと 43 | 44 | Shared Nothing 45 | 46 | lock mutexを無くす 47 | 48 | remote process 49 | 50 | monitor 51 | 52 | * その他の重要項目 53 | 54 | failure 55 | 56 | 耐障害性 57 | 58 | ERTS 59 | 60 | port/ioの並列化 61 | 62 | * erlangの特徴として気づいた点 63 | 64 | hot code upgrade/code loading 65 | 66 | soft real-time/raytency重視 67 | 68 | * coders at work 69 | 70 | 6th joe armstrong 71 | 72 | プログラムはブラックボックスだ。 73 | 74 | 入力と出力があって、関係的な関係があり、 君の問題はどこにあるのか。 75 | 76 | 77 | http://www.sics.se/~joe/thesis/armstrong_thesis_2003.pdf 78 | =============================================================================== 79 | 80 | http://www.trapexit.org/A_Guide_To_The_Erlang_Source 81 | =============================================================================== 82 | 83 | http://basho.com/erlang-at-basho-five-years-later/ 84 | =============================================================================== 85 | 86 | http://www.slideshare.net/barcampcork/erlang-for-five-nines 87 | =============================================================================== 88 | 89 | http://www.slideshare.net/nivertech/erlang-otp 90 | =============================================================================== 91 | 92 | http://www.it.uu.se/research/group/hipe/documents/hipe_manual.pdf 93 | =============================================================================== 94 | 95 | HiPEの大まかな概要と、インターフェースの一覧、 HiPEの外部仕様 96 | 97 | http://www.erlang.se/euc/08/euc_smp.pdf 98 | =============================================================================== 99 | 100 | OSのプロセスに1VMを立てる。 101 | 102 | SMP対応では、複数のschedulerを起動して、run queue を複数のschedulerで処理する。 103 | 104 | runqueueもschedulerごとに分割したいらしいが、今はどうなっているのか。 105 | 106 | runqueueまわりはマクロ多数使っていて、追いきれていない。 107 | 108 | https://www.erlang-solutions.com/sites/default/files/trimedia/ErlangUserGroup-HiPE-DanielLuna.pdf 109 | =============================================================================== 110 | 111 | HiPEのコンパイルフローや中間表現に関して 112 | 113 | Icode :: 114 | 115 | From Beam 116 | To Control Flow Graph 117 | Inline Bifs 118 | SSA form optimizations 119 | Dead code elimination 120 | Constant propagation 121 | Some type tests 122 | Lazy code motion 123 | Back to linear code 124 | 125 | RTL :: 126 | 127 | From Icode 128 | To CFG 129 | SSA 130 | As Icode 131 | Liveness analysis 132 | More optimizations 133 | To Linear code 134 | 135 | Runtime system :: 136 | 137 | HiPE compiler (Erlang) 138 | Mode switch Beam/HiPE (asm) 139 | Glue code for bif calls (m4 macro) 140 | Garbage collection (C) 141 | Stubs for BEAM calls (C and asm) 142 | Loader (C and Erlang) 143 | Signal stack handling (C) 144 | Arithmetic overflow (asm and C) 145 | 146 | http://mydevelopedworld.wordpress.com/2012/12/20/erlang-memory-models-private-heap-vs-shared-heap/ 147 | =============================================================================== 148 | 149 | heapとGCの関係 150 | 151 | http://jlouisramblings.blogspot.jp/2013/01/how-erlang-does-scheduling.html 152 | =============================================================================== 153 | 154 | erlangはプリエンプティブマルチタスク 155 | 156 | golangは 157 | cooperative 158 | -------------------------------------------------------------------------------- /DartVM/src/fix_todo.rst: -------------------------------------------------------------------------------- 1 | 2 | Mintのサイズ 3 | =============================================================================== 4 | Mintは、64bitでも32bitでも64bit幅 5 | x64では、Mintはほぼ存在しない。 6 | ia32の場合は、気にしたコードを書く必要がある。 7 | 8 | nullを含むequality演算に関して 9 | =============================================================================== 10 | 多くのEquality演算は、nullが入ってくる可能性がある。 11 | != nullとした際に、Equality演算の方は、buffとnull型になる。 12 | PolymorphicCallに確定する??? 13 | 14 | むかしはPolymorphiCallだったが、今のEquality系の中間表現は、 15 | nullが入ってもpolymorphicにならないように、nullのケースをEmitする仕組みになっている。 16 | 17 | Representations 18 | =============================================================================== 19 | double型の変数をループで回した場合も、 20 | repreでdoubleからunboxingされる。 21 | 22 | 23 | Polyrmophicの除外 24 | =============================================================================== 25 | toString()はPolyになりやすい。これは例外的。 26 | 組み込み型は、runtime側で実装されており、polyになる可能性がない。 27 | 例をあげると、Listなど。Listの実装はruntimeにある。 28 | 29 | int./ のpoly化 30 | =============================================================================== 31 | issueに報告済み。 32 | intの切り捨て除算は、~/ trunc divが該当するので、注意すること。 33 | 34 | /は、double型の値が返る。 35 | checked-modeだと、doubleになるため、errorかwarningになっている。 36 | 37 | methodの糖衣構文 38 | =============================================================================== 39 | 40 | IC[ smi, double]は、smi型になる。 41 | 42 | (int) a + (double) bは、 43 | a.+(double b)の糖衣構文であるため、aの型に依存したメソッドが呼ばれる。 44 | dartの構文上、2項演算や、第1引数で決まる。 45 | 46 | 47 | Randomクラスが遅い理由 48 | =============================================================================== 49 | smi << がbigintになってめちゃくちゃ遅い。 50 | issueに報告済み。 51 | ボトルネックは、_nextInt32() 52 | int _nextInt32() { 53 | // ここが全体の90% 54 | _state = ((_A * (_state & _MASK_32)) + (_state >> 32)) & _MASK_64; 55 | return _state & _MASK_32; 56 | } 57 | 58 | 59 | 15000くらいで、 _stateが_high, _lowに分割して保持するように修正はいった。 60 | 61 | ia32だと遅いけど、x64だとMintが畳み込まれてそこそこ速くなる見込み。 62 | 63 | intの<<は、どうやってbigint化するのを抑止するのか、今後の改善頼み。 64 | javaのような<<の動作を期待すると遅くなる。移植時の注意点。 65 | 66 | 67 | 68 | optimization_counter_threshold 69 | =============================================================================== 70 | 初期値は2000であるため、オプション操作するとhotcodeの判定回数が変わるはず。 71 | だけど2000以外を指定しても、2000のまま動作する。 72 | 73 | dartvmのコンパイル時にcounter=2000を参照するアセンブラを生成しているらしく、 74 | 実行時には意味のない値になっているかも。 75 | 76 | 最適化コンパイルされた際に、1度も実行されなかった関数が、ICのまま 77 | =============================================================================== 78 | 修正入った。 79 | 最適化コンパイル時に1度も実行されなかったICは、ICのままコンパイルされる。 80 | そのため、特殊化されない。 81 | 82 | 今は、未実行のICは、deoptimize実行命令に置き換えられている。 83 | そのため、最適化コンパイルされた関数を実行した際に、 84 | 1度も実行されていないICを含むパスに入った場合、Deoptimizeされる。 85 | 86 | Float64ArrayCid 87 | =============================================================================== 88 | LoadIndexedInstr::representation()で、 89 | UnboxDouble型であることが付与されている。素晴らしい。 90 | 91 | 92 | Optional Parameterの扱い 93 | =============================================================================== 94 | 冒頭でif elseに展開している。 95 | 96 | List<>のnewの場合、length==0を冒頭で計算して、 97 | Glorableか、Arrayのnewを切り分けている。 98 | 99 | 100 | =============================================================================== 101 | =============================================================================== 102 | =============================================================================== 103 | =============================================================================== 104 | =============================================================================== 105 | =============================================================================== 106 | =============================================================================== 107 | =============================================================================== 108 | =============================================================================== 109 | =============================================================================== 110 | =============================================================================== 111 | =============================================================================== 112 | =============================================================================== 113 | -------------------------------------------------------------------------------- /DartVM/src/async.rst: -------------------------------------------------------------------------------- 1 | async 2 | =============================================================================== 3 | 4 | sample :: 5 | 6 | var f = new File(name).readAsLines(); 7 | f.then((lines) => parse(lines)); 8 | 9 | sdk/lib/io/file.dart :: 10 | 11 | Future> readAsLines([Encoding encoding = Encoding.UTF_8]); 12 | 13 | sdk/lib/io/file_impl.dart :: 14 | 15 | Future> readAsLines([Encoding encoding = Encoding.UTF_8]) { 16 | _ensureFileService(); 17 | Completer> completer = new Completer>(); 18 | return readAsBytes().then((bytes) { 19 | var decoder = _StringDecoders.decoder(encoding); 20 | decoder.write(bytes); 21 | return _getDecodedLines(decoder); 22 | }); 23 | } 24 | 25 | Future> readAsBytes() { 26 | _ensureFileService(); 27 | Completer> completer = new Completer>(); 28 | var chunks = new _BufferList(); 29 | var stream = openInputStream(); 30 | stream.onClosed = () { 31 | var result = chunks.readBytes(chunks.length); 32 | if (result == null) result = []; 33 | completer.complete(result); 34 | }; 35 | stream.onData = () { 36 | var chunk = stream.read(); 37 | chunks.add(chunk); 38 | }; 39 | stream.onError = (e) { 40 | completer.completeError(e); 41 | }; 42 | return completer.future; 43 | } 44 | 45 | streamのonClosed(), onData(), onError() 46 | 47 | onClosedが呼ばれて、処理が完了したときcompleteに値をsetする。 48 | 49 | onErrorで、completeError()にsetする。 50 | 51 | onData()が呼ばれる限りは、addするだけ。 52 | 53 | 54 | 疑問点、、readAsLines()のcompleterは使っていないのでは??? 55 | 56 | もしかして、C++のObjectにbindingして、VM内部のHandle処理に影響を与えるのか? 57 | 58 | Completer 59 | =============================================================================== 60 | completerは、futureでgetするだけのはず。 61 | そしてresultをcompleteで設定すると。 62 | 63 | sdk/lib/async/future_impl.dart :: 64 | 65 | class _CompleterImpl { 66 | future = new _FutureImpl(); 67 | void complete(T value) { 68 | future._setValue(value); 69 | } 70 | 71 | Completerはfutureのwarpperなだけだと思うけど、何かVMに作用するんだっけ? 72 | 73 | Future 74 | =============================================================================== 75 | Futureは、状態付き imcomplete, value, error 76 | 77 | _FutureImplクラスが実体 78 | 79 | factory wait() 80 | 81 | then() 82 | 83 | stateを参照して、 84 | !_isCompleteの場合、 SubscribeToするだけ。 85 | でない場合、Errorを返すか、handleValueを返すか。 86 | 87 | 88 | 89 | VMとの関連 90 | =============================================================================== 91 | timerやstop_watchくらいかな。 とはいっても、OSのplatformの処理を呼ぶだけなんだろうけど。 92 | 93 | 何かweak referenceみたいなの使っているのだろうか。 94 | 95 | 時間を要求した場合、intのオブジェクトを作って返すくらいか。 96 | 97 | 98 | vm/lib 99 | =============================================================================== 100 | vm/lib/async :: 101 | 102 | event_loop_patch.dart 103 | class _AsyncRun 104 | _enqueueImmediate(void callback()) { 105 | Timer.run(callback); 106 | } 107 | timer_patch.dart 108 | class Timer 109 | deferred_load_patch.dart 110 | 111 | Timer.run(void callback()) 112 | =============================================================================== 113 | 114 | _runCallbacks.add(callback) 115 | 116 | length == 1 だったら、 117 | 118 | new Timer(Duration(0), callback) 119 | 120 | lib/timer_patch.dart _TimerFactory._factory() 121 | 122 | class _TimerFactory { 123 | static _TimerFactoryClosure _factory; 124 | } 125 | 126 | どこ読んでるのかわからなかったけど、、sdk/lib/io/timer_impl.dart 127 | ってなんだよ。。 128 | 129 | _createTimer() { 130 | _EventHandler._start(); 131 | if (_timers == null) { 132 | _timers = new DoubleLinkedQueue<_Timer>(); 133 | } 134 | 135 | _Timerを作ってかえす。 136 | 137 | _EventHandler 138 | _start() 139 | _sendData() 140 | 141 | 142 | 143 | 144 | その他 145 | =============================================================================== 146 | 関係あるのは、 147 | bin/dartutils.cc::DartUtils::PrepareForScriptLoading() 148 | 149 | 150 | AsyncRun { 151 | } 152 | 153 | future 154 | =============================================================================== 155 | 156 | then sendValue 157 | 158 | 159 | -------------------------------------------------------------------------------- /golang/garbage_collection.rst: -------------------------------------------------------------------------------- 1 | GC(Garbage Collection) 2 | ############################################################################### 3 | 4 | 場所はpkg/runtime/mgc 5 | 6 | GCの概要 7 | =============================================================================== 8 | 9 | mark&sweep 10 | mostly precise (with the exception of some C-allocated objects, assembly frames/arguments, etc) 11 | parallel (up to MaxGcproc threads) 12 | partially concurrent (mark is stop-the-world, while sweep is concurrent) 13 | non-moving/non-compacting 14 | full (non-partial) 15 | 16 | GOGC=100 17 | 18 | 19 | mgc0 20 | ******************************************************************************* 21 | 22 | mgc0.c 23 | mgc0.go 24 | mgc0.h 25 | 26 | 27 | malloc 28 | =============================================================================== 29 | 30 | GCの概要 31 | =============================================================================== 32 | 33 | GCの起点 34 | =============================================================================== 35 | 36 | 37 | 38 | =============================================================================== 39 | =============================================================================== 40 | =============================================================================== 41 | =============================================================================== 42 | =============================================================================== 43 | 44 | 45 | ******************************************************************************* 46 | 47 | =============================================================================== 48 | =============================================================================== 49 | 50 | heap確保の起点はこれか。 51 | 52 | func new(typ * byte) * any 53 | 54 | もしくは 55 | pkg/builtin :: 56 | 57 | // The new built-in function allocates memory. The first argument is a type, 58 | // not a value, and the value returned is a pointer to a newly 59 | // allocated zero value of that type. 60 | func new(Type) * Type 61 | 62 | pkg/runtime 63 | ******************************************************************************* 64 | 65 | malloc.goc :: 66 | 67 | // Allocate an object of at least size bytes. 68 | // Small objects are allocated from the per-thread cache's free lists. 69 | // Large objects (> 32 kB) are allocated straight from the heap. 70 | // If the block will be freed with runtime·free(), typ must be 0. 71 | void* 72 | runtime.mallocgc(size, typ, flag) 73 | 74 | void 75 | runtime.free(void *v) 76 | 77 | MaxSmallSizeより小さい場合と、大きい場合がある。 :: 78 | 79 | if (size <= MAxSmallSize) { 80 | runtime.size_to_class8[] 81 | runtime.size_to_class128[] 82 | 83 | flag & FlagNoZero 84 | zerofillを制御できる。 85 | c->local_cachealloc += size; 86 | } else { 87 | runtime.MHeap_Alloc() 88 | // setup for mark sweep 89 | runtime.markspan() 90 | } 91 | 92 | FlagNoGCって制御がある 93 | 94 | 95 | =============================================================================== 96 | 97 | =============================================================================== 98 | 99 | 100 | 101 | make channel 102 | ******************************************************************************* 103 | 104 | lex.c 105 | 106 | "make" OMAKE 107 | 108 | "<-" LCOMM 109 | 110 | go.y 111 | =============================================================================== 112 | 113 | expr LCOMM expr 114 | OSEND $1 $3 115 | 116 | LCOMM uexpr 117 | ORECV $2 N 118 | 119 | OTCHAN 120 | Csend 121 | Crecv 122 | 123 | go.h 124 | =============================================================================== 125 | 126 | Crecv ORECV OSELRECV OSELRECV2 127 | Csend OSEND 128 | Cboth Crecv | Csend 129 | 130 | 131 | 132 | 133 | =============================================================================== 134 | 135 | template :: 136 | ############################################################################### 137 | ******************************************************************************* 138 | =============================================================================== 139 | 140 | -------------------------------------------------------------------------------- /art/log.rst: -------------------------------------------------------------------------------- 1 | art git log 2 | ############################################################################### 3 | 4 | 気になったgit logをメモする。 5 | 6 | 更新 2014/05 7 | 8 | 9 | runtime 10 | ******************************************************************************* 11 | 12 | Add thread unsafe allocation methods to spaces 13 | =============================================================================== 14 | 15 | SS/GSS Collectors 16 | AllocThreadUnsafe 17 | 18 | 19 | concurrent Sweeping for non-concurrent GC 20 | =============================================================================== 21 | 22 | semi-space collector 23 | 24 | 25 | deoptimzied shadow frames 26 | =============================================================================== 27 | 28 | 29 | exception handling for deoptimization 30 | =============================================================================== 31 | 32 | QuickExceptionHandler::DeoptimizeStack 33 | 34 | 35 | 36 | =============================================================================== 37 | =============================================================================== 38 | =============================================================================== 39 | =============================================================================== 40 | 41 | compiler 42 | ******************************************************************************* 43 | 44 | kDoReadBarrier 45 | =============================================================================== 46 | 47 | aarch64 48 | =============================================================================== 49 | 50 | aarch64 jni compiler 51 | 52 | 53 | =============================================================================== 54 | 55 | inlining 56 | =============================================================================== 57 | 58 | inlining on trivial accessors 59 | 60 | Inlining synthetic accesors 61 | 62 | Location 63 | =============================================================================== 64 | 65 | Dartっぽい 66 | 67 | RegLocation 68 | 69 | StackLocation 70 | 71 | 72 | 73 | Quick compiler debugging assists 74 | =============================================================================== 75 | 76 | インタプリタに戻らないのか? 77 | 78 | 79 | 80 | Transform to SSA phase to the optimizing compiler 81 | =============================================================================== 82 | 83 | Simplify GenConstString 84 | 85 | Skip BBs without SSA rep 86 | 87 | Constant Propagation phase 88 | 89 | String.IndexOf 90 | 91 | Simplify HInvokeStatic 92 | 93 | optimizing compiler 94 | 95 | add Pass 96 | 97 | AtomicLongの使用 98 | 99 | CFG printing using DOT 100 | 101 | Optimize stack overflow handling 102 | 103 | Plug new optimizing compiler in compilation pipeline. 104 | 105 | 106 | Transpolines 107 | =============================================================================== 108 | 109 | 110 | GC 111 | =============================================================================== 112 | 113 | add GC mode 114 | 115 | 116 | LLVM 117 | =============================================================================== 118 | 119 | コミットは少なめかな。 120 | 121 | LLVMはC++11で書き直されているのでしばらくmergeは無理。 122 | 123 | a Add command line support for enabling the optimizing compiler. 124 | 125 | Also run tests with the optimizing compiler enabled when 126 | the file art/USE_OPTIMIZING_COMPILER is present. 127 | 128 | merged r187914. 2013 Aug 129 | 130 | 131 | 132 | build 133 | =============================================================================== 134 | 135 | SUPPORT arm arm64 mips x86 x86_64 136 | 137 | ARTのMode 138 | 139 | SMALL_MODE 140 | 141 | SEA_IR_MODE 142 | 143 | PORTABLE_COMPILER 144 | 145 | OPTIMIZING_COMPILER 146 | --compiler-backend=Optimizing 147 | 148 | 149 | =============================================================================== 150 | =============================================================================== 151 | 152 | template :: 153 | ############################################################################### 154 | ******************************************************************************* 155 | =============================================================================== 156 | 157 | -------------------------------------------------------------------------------- /DartVM/src/inlining.rst: -------------------------------------------------------------------------------- 1 | Initial support for polymorphic inlining. 2 | 3 | Consider each polymorphic variant separately for inlining in frequency 4 | order. Share inlined bodies for shared targets. 5 | 6 | Insert an SSA redefinition of the receiver in each inlined variant to 7 | prevent hoisting. Hoisting code specialized to the receiver (e.g., 8 | direct access to internal fields of typed data arrays) out of the 9 | inlined body is not safe. 10 | 11 | =============================================================================== 12 | 13 | SortICDataByCount()でソートするのかな。 14 | InheritDeoptTargetなんてものがあるのか。 15 | これでdeoptinfoを調整しないと落ちるのかな。 16 | 17 | 以下のIRを追加 18 | RedefinitionInstr 19 | これはEmitでunreachableなのか。 20 | RemoveRedefinitions()ってのでRangeAnalysisの前に綺麗にする。 21 | これは既存のIRをwrapして、何かするのか。IRのspillみたいなものんか 22 | 23 | LoadClassIdInstr 24 | これはSmiTag用の特殊パスを用意した、LoadClassId 25 | 26 | 本家の処理はInlinerにある 27 | class PolymorphicInliner 28 | PolymorphicInstanceCallをPolymorphicInlinerでinline() 29 | 30 | TryInlining()でRedefinitionInstr()を生成し、calleeのargumentsをwrapするのか。 31 | 32 | Inline() 33 | -> TryInlining() 34 | -> BuildDecisionGraph() 35 | LoadClassIdInstrを生成して、StrictCompareの生成、 36 | 37 | CheckInlineDuplicate()ってのがあって、複数targetの重複をチェックする。。 38 | 基底クラスの同じメソッドを呼び出す場合かな。 39 | 40 | オプション制御はないらしい。 41 | 42 | 43 | 44 | SortICDataByCount() 45 | =============================================================================== 46 | 47 | 下記の2つから呼ばれる :: 48 | 49 | EmitTestAndCall() 50 | GenerateCallを生成する 51 | 52 | PolymorphicInliner::Inline() 53 | 54 | 55 | PolymorphicInliner::Inline() 56 | =============================================================================== 57 | 58 | inline() :: 59 | 60 | SortICDataByCount()でソートして、以下の処理を繰り返す。 61 | CheckInlinedDuplicate() 62 | CheckNonInlinedDuplicate() 63 | TryInlinig() 64 | 65 | 最後に 66 | BuildDecisionGraph() 67 | exit_collector_->ReplaceCall() 68 | 69 | CheckInlinedDuplicateは、異なるクラスから同じメソッドをshareしているか判定する。 70 | 71 | CheckNonInlinedDuplicate()は、他の処理でNonInline判定されたログを確認する処理 72 | たぶんTryInliningでNGだった。 73 | 74 | =============================================================================== 75 | =============================================================================== 76 | 77 | 78 | 79 | inline展開 heuristics 80 | =============================================================================== 81 | 82 | Inlining heuristics based on Cooper et al. 2008. 83 | もしかして、これ? 84 | http://dl.acm.org/citation.cfm?id=1788381 85 | An adaptive strategy for inline substitution 86 | http://www.cs.rice.edu/~keith/512/Lectures/10WholeProgram-1up.pdf 87 | 引数にConstantがある場合、Constant Propagationに期待出きるので、 88 | 積極的にinliningすると。 89 | loop_depthは、loop_depth > 0かつinlining_in_loop_size_thresholdがtrueでないと、 90 | ShouldWeInlineがtrueにならない。 91 | loop bufferの範囲内で、inliningしたいってところか。 92 | 93 | http://www.cs.rice.edu/~keith/512/Lectures/06Opt-V-1up.pdf 94 | 95 | 96 | heuristics 97 | =============================================================================== 98 | ヒューリスティクスに判断すると、以下のいずれかの条件に合致する場合、 99 | inline展開を行う 100 | 101 | DEFINE_FLAG(int, inlining_size_threshold, 22, 102 | "Always inline functions that have threshold or fewer instructions"); 103 | 104 | or 105 | 106 | DEFINE_FLAG(int, inlining_callee_call_sites_threshold, 1, 107 | "Always inline functions containing threshold or fewer calls."); 108 | 109 | or 110 | 111 | DEFINE_FLAG(int, inlining_constant_arguments_count, 1, 112 | "Inline function calls with sufficient constant arguments " 113 | "and up to the increased threshold on instructions"); 114 | 115 | and 116 | 117 | DEFINE_FLAG(int, inlining_constant_arguments_size_threshold, 60, 118 | "Inline function calls with sufficient constant arguments " 119 | "and up to the increased threshold on instructions"); 120 | 121 | 122 | 123 | 124 | Richardsの場合、4関数のpolymorphic inlineだけど、 125 | どれもinline展開しない判断。 126 | 正確には、2つがhearisticsでNG 127 | 2つはnot inlinable 128 | 129 | 130 | bool Function::IsInlineable() const { 131 | // '==' call is handled specially. 132 | return InlinableBit::decode(raw_ptr()->kind_tag_) && 133 | HasCode() && 134 | name() != Symbols::EqualOperator().raw(); 135 | } 136 | 137 | set_is_inlinable 138 | 139 | falseを設定するケースを洗い出す。 140 | 141 | deoptimization_countが多すぎる場合 142 | 再帰関数で、optionがfalse 143 | CanIntrinsify 144 | threshold系で1度falseと判定されたらフラグ管理で埋め込む。 145 | 146 | 147 | 148 | そもそもJVMではどうなのかの解析が必要なのではないか? 149 | -------------------------------------------------------------------------------- /DartVM/src/advent20121218.rst: -------------------------------------------------------------------------------- 1 | Dart VM Advent Calendar 2012 12/18 2 | ############################################################################### 3 | 4 | DartのCore API 5 | =============================================================================== 6 | 7 | Dart SDKのCore APIは、dartだけで記述されていることが少なく、途中からnative extensionを使ってC++実装を呼び出していたり、 8 | 9 | Core APIのクラスと対となる、Dart VM内のC++クラスと紐づいていることが多いです。 10 | 11 | 先々日に紹介したscalarlistパッケージのFloat64Listも、Dart VM内にFloat64Arrayクラスが定義されていました。 12 | 13 | 今回はStringについて紹介しながら、DartのAPIとDart VM間の階層関係をざっくりとみていきます。 14 | 15 | Dartの階層構造 16 | =============================================================================== 17 | dartのcore APIであるStringを例に、どのように階層を重ねているのか。 18 | 19 | 登場するメソッドは、String.concatと、new String()です。 20 | 21 | .. blockdiag:: 22 | 23 | blockdiag { 24 | orientation = portrait 25 | 26 | String -> _StringBase -> NATIVE_ENTRY -> "dart::OneByteString" 27 | 28 | "String.concat" -> "_StringBase.concat" -> "NATIVE_ENTRY(String_concat)" 29 | -> "dart::OneByteString::Concat" 30 | 31 | "new String" -> "_StringBase.createFromCodePoints" -> "NATIVE_ENTRY(StringBase_createFromCodePoints)" 32 | -> "dart::OneByteString::New" -> "dart::RawOneByteString::raw" 33 | "dart::RawOneByteString::raw" -> "uint8_t data_[]" [folded] 34 | 35 | "GC ObjectPointVisitor" -> "dart::RawOneByteString::raw" [dir=forward] 36 | 37 | group { 38 | label="sdk/lib/core/string.dart SDKとして公開される" 39 | String; 40 | "String.concat"; 41 | "new String" 42 | } 43 | 44 | group { 45 | label="runtime/lib/string_base.dart SDKとして公開されない、Internal" 46 | _StringBase; 47 | "_StringBase.concat"; 48 | "_StringBase.createFromCodePoints"; 49 | } 50 | 51 | group { 52 | label="runtime/lib/string.cc Internalから呼ばれる、Nativeなシンボル群" 53 | color=lightgreen 54 | NATIVE_ENTRY; 55 | "NATIVE_ENTRY(String_concat)"; 56 | "NATIVE_ENTRY(StringBase_createFromCodePoints)"; 57 | } 58 | 59 | group { 60 | label="runtime/vm/object RUNTIME_ENTRYから操作されるDartVMが管理するオブジェクト(操作用)" 61 | color=lightblue 62 | "dart::OneByteString"; 63 | "dart::OneByteString::Concat"; 64 | "dart::OneByteString::New"; 65 | } 66 | 67 | group{ 68 | color=lightblue 69 | label="runtime/vm/raw_object DartVMが管理するオブジェクト(データ定義)" 70 | "dart::RawOneByteString::raw"; 71 | "uint8_t data_[]"; 72 | } 73 | } 74 | 75 | DartのAPIの階層は、上記のように階層に分かれます。 ※ ほんとはもっと細かく分かれるかも。。 76 | 77 | dartのライブラリ 78 | =============================================================================== 79 | 80 | Dart SDKのライブラリには、主にsdk/libの下で定義されている、純粋にdartで記述されたライブラリと、 81 | sdk/libから呼ばれる、dartのinternalクラスに分けられます。 82 | 83 | dartのinternalクラスは、高速化のためにC++で記述されたメソッド(native extension)を呼び出します。 84 | 85 | nativeシンボル 86 | =============================================================================== 87 | 88 | Dart VMのnative extensionを使用して、Dart VM内部のstatic関数を、DartのCore APIに対して公開しています。 89 | 90 | native extensionは、JITコンパイルしたコードを紹介した際に登場したStubsや、CallToRuntimeとは違います。 91 | 92 | runtime/libの下で定義されるC++のコードは、DEFINE_NATIVE_ENTRYマクロで定義され、あくまでnative extension機能を使用し、Core APIから呼び出されます。 93 | 94 | CallToRuntimeから呼ばれるシンボルは、runtime/vmの下で定義され、DEFINE_RUNTIME_ENTRYマクロで定義されます。 95 | 96 | Dart VMのオブジェクト 97 | =============================================================================== 98 | 99 | .. image:: png/dart_object.png 100 | 101 | .. image:: png/dart_rawobject.png 102 | 103 | Dartのクラスと対応するDart VM内のクラスは、多くの場合 ObectクラスとRawObjectクラスを継承しています。 104 | 105 | Objectクラスの継承図と、RawObjectクラスの継承図はそっくりです。 106 | 107 | Objectクラスは、主にRawObjectに対する操作のみを定義しています。 108 | 109 | RawObjectクラスは、実データを内包し、管理するクラスです。 110 | 111 | Objectクラスは、実データを定義するRawObjectクラスへの参照を持ち、必ずペアで定義されています。 112 | 113 | そのため、Objectクラスを継承するクラスは、raw_フィールドのみ持ちます。 114 | 115 | また、GCのObjectPointerVisitorは、RawObjectを継承したクラスのみを対象とします。 116 | 117 | GCとの関連 118 | =============================================================================== 119 | GCのVisitorはObjectPointerを辿りながら、GC対象を探します。 120 | 121 | その際GCのVisitorは、RawObjectを継承したクラスのみ辿ります。 122 | 123 | RawObjectは、最初の1wordがObjctTagが埋まっており、2word以降から実データが定義されています。 124 | 125 | 上記のRawOneByteStringの場合、実データはuint8_t[]になりますが、実データは辿りません。RawOneByteStringのインスタンスが、ObjectPointerの末端になります。 126 | 127 | また、RawOneByteStringであるため、uint8_[]のsizeを格納したlengthフィールドが定義されているはずですが、GCのVisitorに辿らせないような配慮がされています。 128 | 129 | RawArrayだった場合には、Arrayとして内包したObjectPointerが多数あるため、GCのVisitorは内包したObjectPointerを辿ります。 130 | 131 | まとめ 132 | =============================================================================== 133 | (1) Coreのクラスと対となるクラスがDart VM内に定義されている。 134 | (2) Dart VM内には、ObjectとRawObjectが存在する。 135 | (3) GCのVisitorが辿るのはRawObject 136 | 137 | 138 | -------------------------------------------------------------------------------- /DartVM/src/memory.rst: -------------------------------------------------------------------------------- 1 | メモリレイアウト 2 | ############################################################################### 3 | 4 | Object 5 | =============================================================================== 6 | 7 | Object.cc::RawObject* Object::Allocate(cls_id, size, space) :: 8 | 9 | //addressがreturnされ、HeapTagが立っていない。 10 | address = heap->Allocate(size, scace); 11 | //nullでsize分初期化したのち、 12 | //tagsをclass_idとsizeから生成して,tags_フィールドに埋め込む。 13 | InitializeObject(address, cls_id, size); 14 | uword tags = 0; 15 | tags = RawObject::ClassIdTag::update(class_id, tags); 16 | tags = RawObject::SizeTag::update(size, tags); 17 | reinterpret_cast(address)->tags_ = tags; 18 | raw_obj = cast(address + heapobjecttag); //heapobjecttag = 1 19 | return raw_obj; 20 | 21 | 22 | [....][....][....][....] <-- size 4byte 23 | ^ 24 | address 25 | 26 | [....][....][....][....] 27 | ^ ^ 28 | tag raw_obj 29 | 30 | RawObject 31 | 32 | Tag 33 | 34 | 35 | 36 | 上記のような扱いのはずだけど。。 37 | 38 | TryAllocate 39 | =============================================================================== 40 | 41 | assembler_ia32.cc :: 42 | 43 | TopAddress() 44 | / 45 | [....][....][....][....] <-- .を1byteとして、[....]は4byte 46 | ^^^^ 47 | 48 | //TopAddressって、すでにkHeapObjectTag加算されてるんだっけ? 49 | addl(instance_reg, Immediate(instance_size)) //TopAddress + instance_size 50 | sub(instance_reg, (instance_size - kHeapObjectTag=1)) //TopAddress - kHeapObjectTag 51 | movl((instance_reg, tags_offset), Immediate(tags)) //tags_フィールドのupdate 52 | return instance_reg 53 | 54 | raw_objectの最初のフィールドはtagで、1word 55 | uword tags_ 56 | 最初の1wordには、必ずtags_を埋め込むということ。 57 | 58 | rawにはtags_があるけど、 59 | marks, size, classが埋まっている。 hashは? 60 | 61 | TagBits :: 62 | 63 | enum TagBits { 64 | kFreeBit = 0, 65 | kMarkBit = 1, //for GC 66 | kCanonicalBit = 2, //for object tags. 67 | kFromSnapshotBit = 3, 68 | kWatchedBit = 4, //for GC 69 | kReservedTagBit = 5, // kReservedBit{10K,100K,1M,10M} 70 | kReservedTagSize = 3, 71 | kSizeTagBit = 8, 72 | kSizeTagSize = 8, 73 | kClassIdTagBit = kSizeTagBit + kSizeTagSize, 74 | kClassIdTagSize = 16 75 | }; 76 | 77 | [....][....][....][....] <-- uword tags_ 78 | ^ ^ ^ 79 | some size classId 80 | 81 | ObjectAlignment :: 82 | 83 | // Alignment offsets are used to determine object age. 84 | kNewObjectAlignmentOffset = kWordSize, //ia32は4 85 | kOldObjectAlignmentOffset = 0, 86 | // Object sizes are aligned to kObjectAlignment. 87 | kObjectAlignment = 2 * kWordSize, 88 | kObjectAlignmentLog2 = kWordSizeLog2 + 1, 89 | kObjectAlignmentMask = kObjectAlignment - 1, 90 | 91 | SizeTag :: 92 | 93 | encodeは、size >> kObjectAlignmentLog2 94 | decodeは、value << kObjectAlignmentLog2 95 | 96 | sizeが8bit目からなので、kObjectAlignment + 1なのだと思う。 97 | 98 | Is :: 99 | 100 | IsHeapObject() 101 | (this & kSmiTagMask) == kHeapObjectTag 102 | 最下位1bit立っているかどうか。 103 | 104 | ia32、word=4, x64、word=8のはず。 105 | 106 | IsNewObject() 107 | (this & kNewObjectAlignmentOffset) == kNewObjectAlignmentOffset 108 | 3or4bit目が立っているかどうか 109 | 110 | IsOldObject() 111 | (this & kNewObjectAlignmentOffset) == kOldObjectAlignmentOffset 112 | 3or4bit目が立っていない。 113 | 114 | なぜ3or4bit目なのかがわからない。。 115 | NewObjectの場合、ObjectAlignmentは8or16だけど、それに1wordずらして扱っている関係上 116 | TopAddressごと 1wordずれているため、とか? 117 | 118 | そんなトリックはheapには見られないけど。。 119 | ダンプを入れると確かに1たってるので。。 120 | 121 | newgen word=4 122 | 123 | snapshot 124 | =============================================================================== 125 | 126 | ReadObjectImpl()を参照すると、 最初にint64_tをReadしている。 :: 127 | 128 | RawObject* SnapshotReader::ReadObjectImpl() { 129 | int64_t value = Read(); 130 | if ((value & kSmiTagMask) == kSmiTag) { 131 | return NewInteger(value); 132 | } 133 | return ReadObjectImpl(value); 134 | } 135 | 136 | // 137 | class_id = GetVMIsolateObjectId(class_header) 138 | 139 | IsVMIsolateObject 140 | 141 | IsSingletonClassId 142 | 143 | IsObjectStoreClassId 144 | 145 | 146 | 147 | 148 | 149 | =============================================================================== 150 | =============================================================================== 151 | 152 | NoGCScope 153 | =============================================================================== 154 | 155 | 156 | 157 | Allocate 158 | =============================================================================== 159 | =============================================================================== 160 | =============================================================================== 161 | -------------------------------------------------------------------------------- /DartVM/src/eventloop.rst: -------------------------------------------------------------------------------- 1 | EventLoop 2 | ############################################################################### 3 | 4 | eventhandler 5 | ******************************************************************************* 6 | 7 | flags :: 8 | 9 | enum MessageFlags { 10 | kInEvent = 0, 11 | kOutEvent = 1, 12 | kErrorEvent = 2, 13 | kCloseEvent = 3, 14 | kDestroyedEvent = 4, 15 | kCloseCommand = 8, 16 | kShutdownReadCommand = 9, 17 | kShutdownWriteCommand = 10, 18 | kReturnTokenCommand = 11, 19 | kListeningSocket = 16, 20 | kPipe = 17, 21 | }; 22 | 23 | Dart_Port port_ 24 | int64_t timeout_ 25 | 26 | class EventHandler 27 | 28 | void SendData(id, port, data) //native EventHandler_SendData 29 | start 30 | stop 31 | delegate 32 | 33 | class EventHandlerImplementation これがOSごとに実装 34 | 35 | io_natives.cc 36 | この中にnative symbolがある 37 | 38 | linux impl 39 | =============================================================================== 40 | 41 | 実装されている関数一覧 :: 42 | 43 | void HandleEvents(struct epoll_event* events, int size); 44 | static void Poll(uword args); 45 | void WakeupHandler(intptr_t id, Dart_Port dart_port, int64_t data); 46 | void HandleInterruptFd(); 47 | void SetPort(intptr_t fd, Dart_Port dart_port, intptr_t mask); 48 | intptr_t GetPollEvents(intptr_t events, SocketData* sd); 49 | static void* GetHashmapKeyFromFd(intptr_t fd); 50 | static uint32_t GetHashmapHashFromFd(intptr_t fd); 51 | 52 | eventhnadlerでは、intptr_t fdからhashmapのkeyを生成している。 53 | 54 | platform/hashmapってのが実装されている。 55 | 56 | int result = dart::Thread::Start(&EventHandlerImplementation::Poll, 57 | reinterpret_cast(handler)); 58 | 59 | epollを使用する 60 | 61 | retryとかの制御はどうなっている? 62 | 63 | NO_RETRY_EXPECTEDマクロで、EINTRまで繰り返す。 64 | 65 | 66 | socketからのコントロール 67 | =============================================================================== 68 | 69 | =============================================================================== 70 | =============================================================================== 71 | =============================================================================== 72 | =============================================================================== 73 | 74 | FileIO read 75 | ******************************************************************************* 76 | 77 | create 78 | =============================================================================== 79 | 80 | Future create 81 | _IOService.dispatch(_FILE_CREATE, [path] 82 | .then((response) 83 | 84 | io_natives 85 | 86 | runtime/bin/io_service.h 87 | にFILE_CREATE等に登録されている。 88 | 89 | FILE_CREATE=1 90 | 91 | #define IO_SERVICE_REQUEST_LIST(V) 92 | 93 | File_Createに変換されてdispatchされている。 94 | 95 | ListStart 96 | ListNext 97 | ListStopとか参考になるかも 98 | 99 | class _IOService 100 | =============================================================================== 101 | 102 | runtime/bin/io_service_patch.dart :: 103 | // Lazy initialize service ports, 32 per isolate. 104 | List _servicePort 105 | RawReceivePort _receivePort 106 | SendPort _replyToPort 107 | Map _messageMap 108 | int _id 109 | 110 | Future dispatch(int request, List data) 111 | do { 112 | _getNextId() 113 | } while () 114 | _servicePort[index].send([id, _replayToPort, request, data) 115 | //ここリストで渡してる 116 | 117 | これを受信しているのは、IOServiceCallback 118 | serviceごとにDart_portを開く。 119 | 120 | :: 121 | 122 | if (message->type == Dart_CObject_kArray && 123 | request.Length() == 4 && 124 | request[0]->IsInt32() && 125 | request[1]->IsSendPort() && 126 | request[2]->IsInt32() && 127 | request[3]->IsArray()) { 128 | 129 | sendのほうの細かい処理はisolateの中に実装。もしくはruntime 130 | 131 | lib/isolate.cc 132 | SendPortImpl_sendInternal 133 | Messageを生成。port.Id(), data, writer.byteswirtten, priority 134 | 135 | 136 | =============================================================================== 137 | =============================================================================== 138 | =============================================================================== 139 | =============================================================================== 140 | =============================================================================== 141 | IOService_NewServicePort 142 | Dart_NewSendPort 143 | isolate, SendPort::New(port_id) 144 | 145 | send 146 | sendto 147 | 148 | 149 | 150 | 151 | class SendPort : public Instance 152 | class RawSendPort 153 | 154 | 155 | =============================================================================== 156 | 157 | template :: 158 | ############################################################################### 159 | ******************************************************************************* 160 | =============================================================================== 161 | 162 | -------------------------------------------------------------------------------- /OpenJDK/bench/DeserBenchmark.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | import sun.misc.Unsafe; 4 | import sun.nio.ch.DirectBuffer; 5 | import java.lang.reflect.Field; 6 | import java.nio.ByteBuffer; 7 | import java.io.File; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | 11 | public class DeserBenchmark { 12 | public static void main(String[] args) throws Exception { 13 | if (args.length != 3) { 14 | System.out.println("usage: "); 15 | System.exit(1); 16 | } 17 | long seed = Long.parseLong(args[0]); 18 | int size = Integer.parseInt(args[1]); 19 | int loop = Integer.parseInt(args[2]); 20 | new DeserBenchmark().run(seed, size, loop); 21 | } 22 | 23 | public void run(long seed, int size, int loop) { 24 | if (seed == 0) { 25 | seed = new Random().nextInt(); 26 | } 27 | 28 | System.out.printf("seed: %d%n", seed); 29 | System.out.printf("size: %d bytes%n", size); 30 | System.out.printf("loop: %d times%n", loop); 31 | byte[] bytes = new byte[size]; 32 | new Random(seed).nextBytes(bytes); 33 | 34 | ByteBuffer heap = ByteBuffer.wrap(bytes); 35 | 36 | ByteBuffer direct = ByteBuffer.allocateDirect(size); 37 | direct.put(bytes); 38 | 39 | // measure("ByteBuffer heap", size, loop, new ByteBufferRunnable(heap)); 40 | measure("ByteBuffer direct", size, loop, new ByteBufferRunnable(direct)); 41 | measure("Unsafe heap", size, loop, new HeapUnsafeRunnable(bytes)); 42 | // measure("Unsafe direct", size, loop, new DirectUnsafeRunnable(direct)); 43 | 44 | System.out.println("writing data to random.data file"); 45 | try { 46 | new FileOutputStream(new File("random.data")).write(bytes); 47 | } catch (IOException ex) { 48 | ex.printStackTrace(); 49 | } 50 | } 51 | 52 | private void measure(String name, int size, int loop, Runnable runnable) { 53 | // warm-up 54 | for (int i=0; i < loop; i++) { 55 | runnable.run(); 56 | } 57 | 58 | long startTime = System.currentTimeMillis(); 59 | 60 | for (int i=0; i < loop; i++) { 61 | runnable.run(); 62 | } 63 | 64 | long time = System.currentTimeMillis() - startTime; 65 | double mbs = size * (long) loop / ((double) time / 1000) / 1024 / 1024; 66 | double msec = time / (double) loop; 67 | 68 | System.out.printf("-- %s%n", name); 69 | System.out.printf(" %.2f msec/loop%n", msec); 70 | System.out.printf(" %.2f MB/s%n", mbs); 71 | } 72 | 73 | private static class ByteBufferRunnable implements Runnable { 74 | private ByteBuffer src; 75 | 76 | public int v32; 77 | public long v64; 78 | 79 | public ByteBufferRunnable(ByteBuffer src) { 80 | this.src = src; 81 | } 82 | 83 | public void run() { 84 | int last = src.limit() - 9; 85 | for(int i=0; i < last; i++) { 86 | byte b = src.get(i); 87 | i++; 88 | if(b < 0) { 89 | v32 = src.getInt(i); 90 | i += 4; 91 | } else { 92 | v64 = src.getLong(i); 93 | i += 8; 94 | } 95 | } 96 | } 97 | } 98 | 99 | private static class UnsafeRunnable implements Runnable { 100 | private static final Unsafe unsafe; 101 | 102 | public int v32; 103 | public long v64; 104 | 105 | static { 106 | try { 107 | Field field = Unsafe.class.getDeclaredField("theUnsafe"); 108 | field.setAccessible(true); 109 | unsafe = (Unsafe) field.get(null); 110 | } catch (Exception e) { 111 | throw new RuntimeException(e); 112 | } 113 | } 114 | 115 | private Object base; 116 | private long address; 117 | private int length; 118 | 119 | public UnsafeRunnable(Object base, long address, int length) { 120 | this.base = base; 121 | this.length = length; 122 | } 123 | 124 | public void run() { 125 | int last = length - 9; 126 | for(int i=0; i < last; i++) { 127 | byte b = unsafe.getByte(base, address + i); 128 | i++; 129 | if(b < 0) { 130 | v32 = unsafe.getInt(base, address + i); 131 | i += 4; 132 | } else { 133 | v64 = unsafe.getLong(base, address + i); 134 | i += 8; 135 | } 136 | } 137 | } 138 | } 139 | 140 | private static class HeapUnsafeRunnable extends UnsafeRunnable { 141 | public HeapUnsafeRunnable(byte[] src) { 142 | super(src, Unsafe.ARRAY_BYTE_BASE_OFFSET, src.length); 143 | } 144 | } 145 | 146 | private static class DirectUnsafeRunnable extends UnsafeRunnable { 147 | public DirectUnsafeRunnable(ByteBuffer src) { 148 | super(src, ((DirectBuffer) src).address(), src.limit()); 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /DartVM/src/advent20121209.rst: -------------------------------------------------------------------------------- 1 | Dart VM Advent Calendar 2012 12/09 2 | ############################################################################### 3 | 4 | Linux Perf Profiling 5 | =============================================================================== 6 | 7 | dartはperfと連携し、実行時の情報を含めてprofilingすることができます。 8 | 9 | 以下のURLでも紹介されています。 10 | 11 | http://code.google.com/p/dart/wiki/Profiling 12 | 13 | 試し方 :: 14 | 15 | $ perf record -f -g dart --generate_perf_events_symbols aobench.dart 16 | $ perf report --call-graph flat 17 | 18 | JITコンパイルしたコードのプロファイル情報を取得できており、ボトルネックの調査がしやすくなっています。 19 | 20 | .. image:: png/perf_aobench.png 21 | 22 | perfで測定時は、dartに--generate_perf_events_symbolsオプションを指定しない場合、 23 | Dart VMは単体のプロセスとしてperfの解析対象となります。 24 | 25 | 以下のような味気ないプロファイル結果になってしまいますのでご注意ください。 26 | 27 | 試し方 :: 28 | 29 | $ perf record -f -g dart aobench.dart 30 | $ perf report --call-graph flat 31 | 32 | これはこれで、ScavengerやMarkingというログがみえていますが、これらはGCです。 33 | 34 | .. image:: png/perf_aobench_notgen.png 35 | 36 | ubuntu12だか、いつかのkernel更新から、perf reportがstdoutにtext形式で結果を出力するのではなく、 37 | 専用のviewerを開くようになりました。 38 | 39 | カーソルで上下移動し、右を押すと対象シンボルのアセンブラ表示に切り替え、 40 | アセンブラ命令のfrequencyをみれるようになってます。 41 | 42 | Dart VMの場合、perf reportする際にはJITコンパイルしたコードが捨てられているので、あまり意味はないです。 43 | 44 | perf連携用ファイルの生成 45 | =============================================================================== 46 | Dart VMは、--generate_perf_events_symbolsオプションを指定した場合、 47 | JITコンパイルしたコードの情報(アドレス、サイズ、シンボル)を記録したファイルを生成しています。 48 | 49 | perfは、record時にDart VMが生成したファイル(/temp/perf-[dart pid].map)を参照します。 50 | 51 | Dart VMは、Process::CurrentProcessId()でdart自体のプロセスIDを取得したのち、 52 | "/tmp/perf-%ld.map", pid というファイルを生成し、以下のようなアドレス、サイズ、シンボル情報を書き込みます。 53 | 54 | pidの参照 :: 55 | 56 | $ ps -la 57 | F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 58 | 0 S 1000 6987 5680 0 80 0 - 1533 wait pts/4 00:00:00 perf.sh 59 | 0 S 1000 6988 6987 0 80 0 - 1388 poll_s pts/4 00:00:00 perf_3.2.0-30 60 | 0 R 1000 6991 6988 96 80 0 - 19996 - pts/4 00:00:05 dart 61 | 0 R 1000 6994 5681 0 80 0 - 1410 - pts/6 00:00:00 ps 62 | 63 | /tmp/perf-6991.mapの中身 :: 64 | 65 | // addr size marker symbol 66 | b3006ef8 10e dart:core__StringBufferImpl@0x36924d72__StringBufferImpl@0x36924d72. 67 | b3007018 a4 dart:core__StringBufferImpl@0x36924d72_clear 68 | b30070d8 30 dart:core__StringBufferImpl@0x36924d72_set__buffer@0x36924d72 69 | b3007118 30 dart:core__StringBufferImpl@0x36924d72_set__length@0x36924d72 70 | b301a228 e file:///home/elise/bench/aobench_inc2.dart_Intersection_get_t 71 | b301a248 30 file:///home/elise/bench/aobench_inc2.dart_Intersection_set_p 72 | b301a288 b23 file:///home/elise/bench/aobench_inc2.dart_AOBench_ambientOcclusion <-- JITコンパイル(非最適化) 73 | b301adc8 e file:///home/elise/bench/aobench_inc2.dart_AOBench_get_NAO_SAMPLES 74 | b301ade8 e file:///home/elise/bench/aobench_inc2.dart_Intersection_get_p 75 | b301ae08 e file:///home/elise/bench/aobench_inc2.dart_Intersection_get_n 76 | b301ae28 49b file:///home/elise/bench/aobench_inc2.dart_AOBench_orthoBasis <-- JITコンパイル(非最適化) 77 | b301b638 bd dart:math_::_cos 78 | b301b708 bd dart:math_::_sin 79 | b301b7d8 101b *file:///home/elise/bench/aobench_inc2.dart_AOBench_ambientOcclusion <-- JITコンパイル(最適化) 80 | b301c808 39b *file:///home/elise/bench/aobench_inc2.dart_Vec_cross 81 | b301cbb8 32c *file:///home/elise/bench/aobench_inc2.dart_Vec_- 82 | b301cef8 d6a *file:///home/elise/bench/aobench_inc2.dart_Sphere_intersect 83 | b301dc78 bf1 *file:///home/elise/bench/aobench_inc2.dart_AOBench_orthoBasis <-- JITコンパイル(最適化) 84 | 85 | アドレスとシンボル情報は、基本的にコンパイル順にファイルに書き出していきます。 86 | 87 | vm/code_observers.cc :: 88 | 89 | virtual void Notify(const char* name, 90 | uword base, 91 | uword prologue_offset, 92 | uword size, 93 | bool optimized) { 94 | const char* format = "%"Px" %"Px" %s%s\n"; // address, asm codesize, marker, symbol 95 | const char* marker = optimized ? "*" : ""; // optimized functionは、markerとして*をつける。 96 | intptr_t len = OS::SNPrint(NULL, 0, format, base, size, marker, name); 97 | char* buffer = Isolate::Current()->current_zone()->Alloc(len + 1); 98 | OS::SNPrint(buffer, len + 1, format, base, size, marker, name); 99 | Dart_FileWriteCallback file_write = Isolate::file_write_callback(); 100 | ASSERT(file_write != NULL); 101 | void* file = Dart::perf_events_file(); 102 | ASSERT(file != NULL); 103 | (*file_write)(buffer, len, file); 104 | } 105 | 106 | 上記Notifyは、JITコンパイルの終了処理において、Code::FinalizeCode()から呼ばれます。 107 | 108 | そのため、非最適化、最適化に限らず、 109 | JITコンパイルされたコードのEntryAddress, Size, Symbolが逐一ファイルに出力されます。 110 | 111 | そのため、記録の粒度はJITコンパイルされた関数単位です。 112 | 113 | OnStackReplacement等、CodeのEntryが複数ある場合、ちょっと工夫しないといけないかもです。 114 | 115 | MultiThread Profiling 116 | =============================================================================== 117 | 118 | 最近、intel VTUNE用インターフェースも追加されましたが、そちらはまだ試せていないです。 119 | 120 | isolateを複数生成した重い処理を行った際に、VTUNEでどのように見えるのか試してみたいです。 121 | 122 | .. note :: 123 | 124 | LLVMがVTUNEによるJIT Profiling対応してのも今年からだったかな。3.2から? 125 | 126 | まとめ 127 | =============================================================================== 128 | (1) perfを使えば、jITコンパイルしたコードのプロファイル情報を手軽に取得できる。 129 | (2) perfと連携するため、アドレス、サイズ、シンボル情報をファイルに出力している。 130 | -------------------------------------------------------------------------------- /DartVM/src/advent20121205.rst: -------------------------------------------------------------------------------- 1 | Dart VM Advent Calendar 2012 12/05 2 | ############################################################################### 3 | 4 | Dart VMの概要(2) 5 | =============================================================================== 6 | 7 | 続いて、fibo関数です。 8 | 9 | .. literalinclude:: out/fibo.dart 10 | 11 | Dart VMの実行の流れ、続き 12 | =============================================================================== 13 | 14 | 前回のアセンブラ抜粋 :: 15 | 16 | //main body 17 | t0 <- Constant:3(#40) 18 | PushArgument:4(t0) 19 | StaticCall:5(fibo t0) 20 | 0xb2f8817c b850000000 mov eax,0x50 <-- fiboの引数40 21 | 0xb2f88181 50 push eax 22 | 0xb2f88182 bab16b03b3 mov edx,0xb3036bb1 Array[1, 1, null] 23 | 0xb2f88187 e87c823702 call 0xb5300408 [stub: CallStaticFunction] <-- Stub越しにfibo呼び出し 24 | 0xb2f8818c 83c404 add esp,0x4 25 | 26 | Stub越しにfiboをcallしたところから。 27 | 28 | StubのCallStaticFunctionは、fibo関数がコンパイル済みかチェックし、 29 | 30 | コンパイルされていなければJITコンパイル(非最適化)してコードを生成します。 31 | 32 | コードをコンパイルしてpatchingした後は、以後コンパイルチェック処理には飛ばず、 33 | 34 | 生成したコードに直接飛びます。 35 | 36 | fiboの中間表現(非最適化) 37 | =============================================================================== 38 | .. literalinclude:: out/fibo.fibo.ir 39 | 40 | 特徴は、(+)や(-)演算も、InstanceCallで呼び出している点です。 41 | 42 | Dartは言語仕様において、a + bは、a.(+)(b) のようなメソッド呼び出しの糖衣構文だそうです。 43 | 44 | そのため、変数aの型のメソッド(+)を、変数aのthisポインタと、変数bを引数に呼び出すイメージかな? 45 | 46 | InstanceCallはさらに特殊な命令で、InstanceCallから生成されるアセンブラコードの中で、 47 | 変数aと変数bの型を記録する処理が入っています。 48 | 49 | Dart VMの型情報の収集は、InstanceCallの中で行うと考えてOKです。 50 | 51 | 最初の(n-1)は、n(40)も1もint(Smi型)であるため、 52 | InstanceCall(-) では、InstanceCall(-)は、(Smi型,Smi型)から呼ばれたと記録されます。 53 | 54 | fiboのアセンブラ(非最適化) 55 | =============================================================================== 56 | .. literalinclude:: out/fibo.fibo.asm 57 | 58 | 非常に面白いのは、Branch if ReleationalOp()が、callになっている点。 59 | 60 | Dart VMでは、比較処理自体も、InstancCallのような呼び出しになっており、 61 | かつ呼び出し先で型情報を収集する。 62 | 63 | それなら、比較処理自体をInstanceCallとgotoの2中間表現に分けてしまってよいように思うが、 64 | 両者を融合した、非常に大粒な中間表現にしている。それには理由があるが、後で。 65 | 66 | JITコンパイラ(非最適化)が生成したコードはどんな型でも動作する。 67 | =============================================================================== 68 | 69 | ここでちょっと注意点なのですが、Dart VMのJITコンパイラ(非最適化)が生成したコードはどんな型でも動作します。 70 | 71 | DartはOptional Typeであり、コンパイル時に型を参照してWarningは発生しますが、 72 | ソースコードに書いた型情報は、Runtimeに何の作用も及ぼさないように設計されています。 73 | 74 | そのため、ソースコードと中間表現は以下のような対応を取ります。 75 | 76 | イメージ図 :: 77 | 78 | ソースコード 中間表現 79 | int n=0 ; n = n + 1; --> InstanceCall(+, n, 1) 80 | double n=0.0; n = n + 1; --> InstanceCall(+, n, 1) 81 | Point n=p ; n = n + 1; --> InstanceCall(+, n, 1) 82 | var n=0 ; n = n + 1; --> InstanceCall(+, n, 1) 83 | 84 | しかし、実行するコードではそうはいかないです。 :: 85 | 86 | ソースコード 中間表現 コード 87 | int n=0 ; n = n + 1; --> InstanceCall(+, n, 1) --> ((Smi)n) .(add)((smi)1) 88 | double n=0.0; n = n + 1; --> InstanceCall(+, n, 1) --> ((double)n).(add)((smi)1) 89 | Point n=p ; n = n + 1; --> InstanceCall(+, n, 1) --> ((Point)n) .(add)((smi)1) 90 | var n=0 ; n = n + 1; --> InstanceCall(+, n, 1) --> ((Smi)n) .(add)((smi)1) 91 | 92 | コード上では、Runtimeの型に応じて、呼び出すメソッドを切り替える必要があります。 93 | 94 | 多くの動的型付け言語の処理系は、上記のような処理を、インタプリタが行っているはずです。 95 | 96 | しかしJITコンパイルするDart VMは、 97 | 上記のように型情報を参照して動的メソッドディスパッチするコードを生成しておきます。 98 | 99 | そのため、(+)や(<)などの基本演算も、すべてメソッドになります。 100 | 101 | .. note:: 102 | 103 | DartはPreCompile時には静的型付けですが、Runtimeでは動的型付けなので、、 104 | 105 | Dartは、receiver型の動的ディスパッチです。第1引数(thisポインタ?)のみ参照する。 106 | 107 | そのため、fibo(int n)とfibo(double n)はRuntime時に定義が衝突してエラーになります。 108 | 109 | 110 | そのため、以下のTwoArgsCheckInlineCacheのStub呼び出しは、 111 | 引数にどんな型が来ても、呼び出し先のメソッドを適切に選んで、目的の(+)メソッドを呼び出します。 112 | 113 | TwoArgsCheckInlineCache :: 114 | 115 | mov ecx,0xb32d06f1 'ICData target:'+' num-checks: 0' 116 | mov edx,0xb31eba89 Array[2, 2, null] 117 | call 0xb30402d8 [stub: TwoArgsCheckInlineCache] //2引数のInlineCache 118 | add esp,0x8 119 | 120 | しかし、呼び出す(+)メソッドの候補は多数あり、毎回探して呼び出すと性能劣化が懸念されます。 121 | 122 | そのため、InlineCacheという動的メソッドディスパッチの最適化方法を使用します。 123 | 124 | InlineCache 125 | =============================================================================== 126 | 中間表現上で、RelationalOpやInstanceCallだった命令が、 127 | コード上ではTwoArgsCheckInlineCacheのstub呼び出しに変換されています。 128 | 129 | InlineCacheは、多型のメソッドディスパッチを高速化するため、 130 | よく呼ばれる型をキャッシュしておき、高速に呼び出せるようにする仕組みです。 131 | 132 | 動的型付けだとしても、calleeが呼び出すメソッドは同じであることが多いため、高速に動作します。 133 | 134 | InlineCacheは、calleeごとにCacheを持ち、メソッド呼び出し履歴を記録します。 135 | 136 | fiboが呼び出すメソッド、(<)と(-)と(-)と(+)の4ヶ所で、各々がCacheテーブルを持つはずです。 137 | 138 | また、TwoArgsCheckInlineCacheのStubは、未解決クラスのloadとJITコンパイルも行うことができます。 139 | 140 | 仮に未解決のPointクラスの(+)メソッドを呼び出す場合、以下の手順が必要でしょう。 141 | 142 | (1) Pointクラスを探す。 143 | (2) Pointクラスに(+)メソッドが定義されているか確認。 144 | (3) (+)メソッドをJITコンパイルしてコードを生成する。 145 | 146 | 次回、最適化JITコンパイル!!! 147 | =============================================================================== 148 | fiboはfiboを再帰呼び出しするため、いつかは呼び出し回数2000回を越えて、 149 | OptimizeFunctionの呼び出しにより、再コンパイル(最適化)されることになる。 150 | 151 | 最適化する際には、InlineCacheやInstanceCallの呼び出し時に情報収集した型情報を活用して、 152 | 高速なコードを生成します。 153 | 154 | 続きは次回で。。 155 | 156 | まとめ 157 | =============================================================================== 158 | (1) +や-や<演算子は、InlineCacheになる。 159 | (2) InlineCacheの中で、型情報を収集する。 160 | (3) fiboは再帰呼び出しで、次回最適化JITコンパイルされそう!!! 161 | 162 | -------------------------------------------------------------------------------- /DartVM/src/branch.rst: -------------------------------------------------------------------------------- 1 | branch 2 | ############################################################################### 3 | current - 29800 4 | randomの追加 5 | 6 | AndImmediate 7 | TestImmediate 8 | 9 | ControlInstruction rename -> BranchInstr 10 | 11 | TestSmiInstr 12 | a and b == 0のケースで置換する 13 | 14 | 15 | 16 | 17 | ******************************************************************************* 18 | 19 | =============================================================================== 20 | =============================================================================== 21 | 22 | 23 | ******************************************************************************* 24 | 25 | =============================================================================== 26 | =============================================================================== 27 | 28 | 29 | 30 | 31 | r30119 | srdjan@google.com | 2013-11-09 02:42:45 +0900 (土, 09 11月 2013) | 5 lines 32 | Constant fold strict comparison based on incoming types: 33 | different (exact) types means that the result is false. 34 | LoadStaticField computes type for final fields. Make a temporary buffer final. 35 | R=kmillikin@google.com 36 | Review URL: https://codereview.chromium.org//57703004 37 | 特定条件化でdynamicでない場合、kEQ_STRICT に変換 38 | 39 | 40 | r30058 | fschneider@google.com | 2013-11-08 02:27:16 +0900 (金, 08 11月 2013) | 10 lines 41 | VM: Fix identical comparisons with bigints. 42 | 43 | The optimizing compiler did not properly preserve registers across 44 | the runtime call that occurs when using identical with bigints. 45 | 46 | BUG=http://dartbug.com/14903 47 | TEST=tests/language/vm/regress_14903_test.dart 48 | R=srdjan@google.com 49 | Review URL: https://codereview.chromium.org//64723002 50 | 51 | 52 | 53 | 54 | 55 | 56 | neider@google.com | 2013-11-07 20:47:04 +0900 (木, 07 11月 2013) | 31 lines 57 | Cleanup of branch code generation (no change in functionality). 58 | This CL is the first step in refactoring the way branches and comparisons are generated. 59 | 60 | 1. Move helper functions from flow_graph_compiler_xyz.cc to 61 | intermediate_language_xyz.cc. 62 | 63 | 2. Remove IL class ControlInstruction. It was only implemented by BranchInstr. 64 | All functions provided are moved to BranchInstr. 65 | 66 | 3. When generating branch code for comparisons, pass the successor labels explicitly 67 | instead of getting them from the branch. This will allow us to provide different labels 68 | when materialize a bool value of a comparison. 69 | 70 | 4. Move some common code for IfThenElseInstr from the platform-specific files 71 | into intermediate_language.cc and simplify it. 72 | 73 | The goal is to enable if-conversion of arbitrary comparisons. Right now, 74 | the code for == is hard-coded in IfThenElseInstr (and duplicated, too). This 75 | means that e.g. "a < b ? 0 : 1" cannot be optimized. 76 | 77 | 78 | 79 | s a result, IfThenElseInstr can be used to materialize the boolean value of 80 | a comparison. This way the complication of having ComparisonInstr both as a 81 | normal instruction and as wrapped inside a BranchInstr can be simplified. 82 | Comparisons would no longer appear as plain instructions in the IL, but only 83 | wrapped inside either a Branch or an IfThenElse(true, false). 84 | 85 | R=zra@google.com 86 | Review URL: https://codereview.chromium.org//62133002 87 | これもcompareの最適化 88 | 89 | 90 | 91 | 92 | r29985 | fschneider@google.com | 2013-11-07 03:28:37 +0900 (木, 07 11月 2013) | 11 lines 93 | VM: Fix double comparisons using != and NaN in optimized code. 94 | 95 | With a double x 96 | 97 | x == double.NAN should false and x != double.NAN should be true. 98 | 99 | TEST=tests/language/double_nan_comparison_test.dart 100 | BUG=https://code.google.com/p/dart/issues/detail?id=14867 101 | R=srdjan@google.com 102 | Review URL: https://codereview.chromium.org//62443002 103 | 104 | 105 | 106 | neider@google.com | 2013-11-06 21:13:29 +0900 (水, 06 11月 2013) | 14 lines 107 | Merge (x & y) == 0 pattern to emit a single test instruction. 108 | 109 | This is based on a previous uncommitted CL by vegorov@ 110 | (https://codereview.chromium.org/14251023/). 111 | 112 | It is rebased and fixes a bug in the MIPS implementation: BranchOnCondition 113 | requires the comparison result in fixed registers CMPRES1/CMPRES2. 114 | 115 | Remove register alias TMP1 (=TMP) and CMPRES (=CMPRES1). It is confusing to 116 | have them around and easy to forget that they are actually the same. 117 | 118 | R=srdjan@google.com, zra@google.com 119 | Review URL: https://codereview.chromium.org//59613005 120 | 121 | TestSmiInstrを追加 122 | RecognizedTestPattern (a & b) == 0 123 | 124 | 普通にtestlアセンブラを出力する。 125 | 126 | 127 | 128 | 129 | r29800 | fschneider@google.com | 2013-11-04 20:32:52 +0900 (月, 04 11月 2013) | 15 lines 130 | Change == into an instance call to allow polymorphic inlining of ==. 131 | 132 | In unoptimized code equality is now just another instance call. 133 | 134 | The optimizer replaces it with a specialized implementation based on static 135 | type information and type feedback. 136 | 137 | Many of the manual optimizations of == in the optimizer are now just handled 138 | by the generic inliner, plus polymorphic inlining of == calls is now possible. 139 | This also eliminates the need for a lot of duplicated code in the backend. 140 | 141 | I adapted the inlining heuristics to compensate for the slightly larger inital flow graph size. 142 | Review URL: https://codereview.chromium.org//27307005 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /OpenJDK/bench/deser_benchmark.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #if defined(__BIG_ENDIAN__) || (defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN) 14 | # error architecture must be little endian 15 | #endif 16 | 17 | #if defined(_byteswap_uint64) || (defined(_MSC_VER) && _MSC_VER >= 1400) 18 | # define _ntohll(x) (_byteswap_uint64(x)) 19 | #elif defined(bswap_64) 20 | # define _ntohll(x) bswap_64(x) 21 | #elif defined(__DARWIN_OSSwapInt64) 22 | # define _ntohll(x) __DARWIN_OSSwapInt64(x) 23 | #else 24 | # warn _ntohll by bitshift 25 | # define _ntohll(x) \ 26 | ( ((((uint64_t)x) << 56) ) | \ 27 | ((((uint64_t)x) << 40) & 0x00ff000000000000ULL ) | \ 28 | ((((uint64_t)x) << 24) & 0x0000ff0000000000ULL ) | \ 29 | ((((uint64_t)x) << 8) & 0x000000ff00000000ULL ) | \ 30 | ((((uint64_t)x) >> 8) & 0x00000000ff000000ULL ) | \ 31 | ((((uint64_t)x) >> 24) & 0x0000000000ff0000ULL ) | \ 32 | ((((uint64_t)x) >> 40) & 0x000000000000ff00ULL ) | \ 33 | ((((uint64_t)x) >> 56) ) ) 34 | #endif 35 | 36 | #define _load32(dst, src, type) \ 37 | do { \ 38 | memcpy((type*) (dst), (src), sizeof(type)); \ 39 | *(dst) = ntohl(*(dst)); \ 40 | } while (0); 41 | 42 | #define _load64(dst, src, type) \ 43 | do { \ 44 | memcpy((type*) (dst), (src), sizeof(type)); \ 45 | *(dst) = _ntohll(*(dst)); \ 46 | } while (0); 47 | 48 | #define _shift32(dst, src, type) (*(dst) = (type) ( \ 49 | (((uint32_t)((uint8_t*)(src))[0]) << 24) | \ 50 | (((uint32_t)((uint8_t*)(src))[1]) << 16) | \ 51 | (((uint32_t)((uint8_t*)(src))[2]) << 8) | \ 52 | (((uint32_t)((uint8_t*)(src))[3]) ) )) 53 | 54 | #define _shift64(dst, src, type) (*(dst) = (type) ( \ 55 | (((uint64_t)((uint8_t*)(src))[0]) << 56) | \ 56 | (((uint64_t)((uint8_t*)(src))[1]) << 48) | \ 57 | (((uint64_t)((uint8_t*)(src))[2]) << 40) | \ 58 | (((uint64_t)((uint8_t*)(src))[3]) << 32) | \ 59 | (((uint64_t)((uint8_t*)(src))[4]) << 24) | \ 60 | (((uint64_t)((uint8_t*)(src))[5]) << 16) | \ 61 | (((uint64_t)((uint8_t*)(src))[6]) << 8) | \ 62 | (((uint64_t)((uint8_t*)(src))[7]) ) )) 63 | 64 | #define FILE_PATH "random.data" 65 | 66 | static volatile int32_t v32; 67 | static volatile int64_t v64; 68 | 69 | static void run_shift(const char* data, size_t size) 70 | { 71 | const size_t last = size - 9; 72 | for(size_t i=0; i < last; i++) { 73 | char b = data[i]; 74 | i++; 75 | if(b < 0) { 76 | _shift32(&v32, data + i, int32_t); 77 | i += 4; 78 | } else { 79 | _shift64(&v64, data + i, int64_t); 80 | i += 8; 81 | } 82 | } 83 | } 84 | 85 | static void run_load(const char* data, size_t size) 86 | { 87 | const size_t last = size - 9; 88 | for(size_t i=0; i < last; i++) { 89 | char b = data[i]; 90 | i++; 91 | if(b < 0) { 92 | _load32(&v32, data + i, int32_t); 93 | i += 4; 94 | } else { 95 | _load64(&v64, data + i, int64_t); 96 | i += 8; 97 | } 98 | } 99 | } 100 | 101 | static void show_measured(const char* name, 102 | size_t size, int loop, 103 | const struct timeval* start, const struct timeval* finish) 104 | { 105 | double time = 106 | (finish->tv_sec - start->tv_sec) * 1000.0 + 107 | (finish->tv_usec - start->tv_usec) / 1000.0; 108 | double msec = time / loop; 109 | double mbs = size * loop / (time / 1000) / 1024 / 1024; 110 | 111 | printf("-- %s\n", name); 112 | printf(" %.2f msec/loop\n", msec); 113 | printf(" %.2f MB/s\n", mbs); 114 | 115 | } 116 | 117 | int main(void) 118 | { 119 | const int loop = LOOP; // compile with -DLOOP=N option 120 | 121 | int fd = open(FILE_PATH, O_RDONLY); 122 | 123 | struct stat stbuf; 124 | fstat(fd, &stbuf); 125 | size_t size = stbuf.st_size; 126 | 127 | char* map = mmap(NULL, size, PROT_READ, 128 | MAP_SHARED, fd, 0); 129 | 130 | printf("size: %lu\n", size); 131 | printf("loop: %u times\n", loop); 132 | 133 | { 134 | // warm-up 135 | for(int i=0; i < loop; i++) { 136 | run_load(map, size); 137 | } 138 | 139 | struct timeval start; 140 | gettimeofday(&start, NULL); 141 | 142 | for(int i=0; i < loop; i++) { 143 | run_load(map, size); 144 | } 145 | 146 | struct timeval finish; 147 | gettimeofday(&finish, NULL); 148 | 149 | show_measured("C load", size, loop, &start, &finish); 150 | } 151 | 152 | { 153 | // warm-up 154 | for(int i=0; i < loop; i++) { 155 | run_shift(map, size); 156 | } 157 | 158 | struct timeval start; 159 | gettimeofday(&start, NULL); 160 | 161 | for(int i=0; i < loop; i++) { 162 | run_shift(map, size); 163 | } 164 | 165 | struct timeval finish; 166 | gettimeofday(&finish, NULL); 167 | 168 | show_measured("C shift", size, loop, &start, &finish); 169 | } 170 | 171 | munmap(map, size); 172 | } 173 | --------------------------------------------------------------------------------