├── 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 |
--------------------------------------------------------------------------------