Upload
ytoshima
View
1.753
Download
12
Tags:
Embed Size (px)
DESCRIPTION
Memos for HotSpot template interpreter
Citation preview
Objects in Virtual Machine
All java objects have common header called oopDesc. oopDesc has two f ields mark and klass. These f ields have the same size aspointer €32- bit in 32- bit VM and 64- bit in 64- bit VM
Lowest two bits are used for object state.
mark klass
Used by Mark&Sweep to mark obj is not validMarked11PtrInf lated lockMonitor10PtrRegular object headerUnlocked01HeaderPtr points real header on stacklocked00Ptrdescript ionStateLow two bitsHigher bits
Objects in Virtual Machine0x684d2448: oopDesc {0x684d2448: markOop _mark; 0x000000010x684d244c: klassOop _klass; 0x684000f00x684d244c: }0x684d2450: klassOopDesc {0x684d2450: u4 _vtbl; 0x6ff2f3180x684d2458: klassOop cache_0; 0x684d24480x684d245c: klassOop cache_1; 0x684d24480x684d2460: klassOop cache_2; 0x6840ab880x684d2464: klassOop cache_3; 0x000000000x684d2468: int _size_helper; 0x000000040x684d246c: int _exact_instance_size; 0x000000030x684d2470: oop _java_mirror; 0x684d25280x684d2474: klassOop _super; 0x684032300x684d2478: symbolOop _name; 0x684af5100x684d247c: AccessFlags _access_flags; 0x000000210x684d2480: klassOop _subklass; 0x000000000x684d2484: klassOop _next_sibling; 0x684d1e100x684d2488: juint _alloc_count; 0x000000000x684d2488: }
0x684d2490: instanceKlass {0x684d2490: klassOop _array_klasses; 0x000000000x684d2494: objArrayOop _methods; 0x684d22080x684d2498: typeArrayOop _method_ordering; 0x68400c180x684d249c: objArrayOop _local_interfaces; 0x68400c280x684d24a0: objArrayOop _transitive_interfaces; 0x68400c280x684d24a4: int _nof_implementors; 0x000000000x684d24a8: klassOop _implementor; 0x000000000x684d24ac: typeArrayOop _fields; 0x684d21f00x684d24b0: constantPoolOop _constants; 0x684d20100x684d24b4: oop _class_loader; 0x6d41b0300x684d24b8: oop _protection_domain; 0x6d42a0780x684d24bc: objArrayOop _signers; 0x000000000x684d24c0: symbolOop _source_file_name; 0x684d21b00x684d24c4: typeArrayOop _inner_classes; 0x68400c080x684d24c8: int _nonstatic_field_size; 0x000000010x684d24cc: int _static_field_size; 0x000000000x684d24d0: int _static_oop_field_count; 0x000000000x684d24d4: int _nonstatic_oop_map_size; 0x000000010x684d24d8: bool _is_marked_dependent; 0x000x684d24dc: ClassState _init_state; 0x000000040x684d24e0: Thread* _init_thread; 0x0000e0e80x684d24e4: int _vtable_len; 0x000000070x684d24e8: int _itable_len; 0x000000000x684d24ec: ReferenceType _reference_type; 0x000000000x684d24f0: OopMapCache* _oop_map_cache; 0x000000000x684d24f4: JNIid* _jni_ids; 0x0000ec200x684d24f8: nmethod* _osr_nmethod_head; 0x000000000x684d24fc: BreakpointInfo* _breakpoints; 0x000000000x684d24fc: }
Objects in Virtual Machine0x684d2228: oopDesc {0x684d2228: markOop _mark; 0x000000010x684d222c: klassOop _klass; 0x684008e00x684d222c: }0x684d2230: methodOopDesc {0x684d2230: constantPoolOop _constants; 0x684d20100x684d2234: typeArrayOop _exception_table; 0x68400c180x684d2238: u2 _method_size; 0x00180x684d223a: u2 _max_stack; 0x00030x684d223c: u2 _max_locals; 0x00010x684d223e: u2 _size_of_parameters; 0x00010x684d2240: u2 _name_index; 0x00130x684d2242: u2 _signature_index; 0x00140x684d2244: u2 _null_cast_cache; 0xffff0x684d2246: u1 _null_cast_seen; 0x000x684d2247: u1 _range_check_fail; 0x000x684d2248: u1 _interpreter_throwout_count; 0x00000x684d224c: AccessFlags _access_flag; 0x001000010x684d2250: u2 _code_size; 0x00100x684d2252: u2 _parameter_info; 0x00000x684d2254: int _vtable_index; 0xffffffff0x684d2258: int _invocation_counter; 0x000000090x684d225c: int _interpreter_invocation_count; 0x000000010x684d2260: nmethod* _code; 0x000000000x684d2264: address _interpreter_entry; 0x000633200x684d2268: address _from_compiled_code_entry_point; 0x6dc023300x684d226c: int _deopt_range_check_count; 0x000000000x684d226c: }
0x684d2010: oopDesc {0x684d2010: markOop _mark; 0x000000010x684d2014: klassOop _klass; 0x684009300x684d2014: }0x684d2018: arrayOopDesc {0x684d2018: u4 _length; 0x000000350x684d2018: }0x684d201c: constantPoolOopDesc {0x684d201c: typeArrayOop _tags; 0x684d21000x684d2020: constantPoolCacheOop _cache; 0x684d25400x684d2024: klassOop _pool_holder; 0x684d24480x684d2024: }
0x684d2020: 0x684d2540 0x684d2448 0x00000000 0x001e00020x684d2030: 0x68403230 0x0020000b 0x00220021 0x00240023 0x684d2040: 0x00000000 0x000f4240 0x00260025 0x68401848 0x684d2050: 0x0028000b 0x684d2448 0x001e000b 0x00000000 0x684d2060: 0x00000004 0x684d25f8 0x002b000b 0x684d2148 0x684d2070: 0x6840f468 0x68401da0 0x684021f0 0x68401360 0x684d2080: 0x68401390 0x684d2158 0x684d2170 0x684d2198 0x684d2090: 0x68401e08 0x68402388 0x68401308 0x684d21b0 0x684d20a0: 0x00140013 0x68400c80 0x00120011 0x68438338
Objects in Virtual Machine0x684af510: oopDesc {0x684af510: markOop _mark; 0x00c0b9e90x684af514: klassOop _klass; 0x684001900x684af514: }0x684af518: symbolOopDesc {0x684af518: symbolOop _next; 0x000000000x684af51c: u2 _length; 0x00070x684af51e: u2 _data; 0x00200x684af51e: }
0x684d2010: oopDesc {0x684d2010: u4 _mark; 0x000000010x684d2014: u4 _klass; 0x684009300x684d2014: }0x684d2018: arrayOopDesc {0x684d2018: u4 _length; 0x000000350x684d2018: }0x684d201c: constantPoolOopDesc {0x684d201c: typeArrayOop _tags; 0x684d21000x684d2020: constantPoolCacheOop _cache; 0x684d25400x684d2024: klassOop _pool_holder; 0x684d24480x684d2024: }
0x684d2020: 0x684d2540 0x684d2448 0x00000000 0x001e00020x684d2030: 0x68403230 0x0020000b 0x00220021 0x00240023 0x684d2040: 0x00000000 0x000f4240 0x00260025 0x68401848 0x684d2050: 0x0028000b 0x684d2448 0x001e000b 0x00000000 0x684d2060: 0x00000004 0x684d25f8 0x002b000b 0x684d2148 0x684d2070: 0x6840f468 0x68401da0 0x684021f0 0x68401360 0x684d2080: 0x68401390 0x684d2158 0x684d2170 0x684d2198 0x684d2090: 0x68401e08 0x68402388 0x68401308 0x684d21b0 0x684d20a0: 0x00140013 0x68400c80 0x00120011 0x68438338
InterpreterAbst r act In t er p r et er _en t r y_t ab le
zerolocals
zerolocals_synchronized
empty
accessor
abstract
java_lang_math_sin
java_lang_math_cos
java_lang_math_sqrt
native
native_synchronized
St u b Qu eu e in st an ce
_stub_buffer
Disp atchTab l e
_normal_table
_active_table
_safept_table
atos
itos
ltos
ftos
vtos
_size
_description
_safe
_bytecode
instructionsfor bytecode
atos entry
vtos entry
entry indexed by bytecode
In t er p r et er Cod elet
バイトコードは Java method がネイティブ命令(nmethod)にコンパイルされるまではインタープリタで実行される
AbstractInterpreter が大半の interpreter のデータを含むtemplate interpreter はバイトコード実行に dispatch table をしよう。このテーブルは各バイトコードに対応したマシン命令の entry point のテーブル。active table が現在のテーブルをさし、通常時は normal table, GC などで Safepoint sync がかかっていると safepoint table を指す。
dispatch table は top of stack の状態により atos, itos, ltos などがあり、現在の命令の終了時の top of stack により次の命令への入り方を切り替える。top of stack の状態が前後で合えば、stack にストアする事なしに、レジスタで値を渡せる。
簡単なローカル変数、expression stack への変更などは短いネイティブ命令のシーケンスで実行。複雑な仕事、constant pool からの値のロード、バイトコード書き換えなどは call_VM で InterpreterRuntime, SharedRuntime にぬける
AbstractInterpreter には entry table と呼ばれる物があり、メソッドが呼ばれる場合に、メソッドの属性に応じたエントリに invoke* から飛ぶ。新しいメソッドに入る段階での interpreter frame を作ったり、synchronized method には BasicObjectLock をフレームに作る。
- accessibility check- nmethod ができていればそちらに飛ぶ- interpreter frame の更新、セーブ- BasicObjectLock 確保- invocation counter 更新- メソッドの最初のバイトコードへのディスパッチ
生成された template interpreter の例 (java7 beta)https://gist.github.com/1305383
ダンプに使用したマクロhttps://gist.github.com/1305383#file_java7interp.mac
MethodHandle には invokeExact:(String;CC)String というメソッドは無いのになぜ呼び出せるのか
96: aload 6! ! // MethodHandle 98: ldc #22; //String daddy 100: bipush 100 102: bipush 110 104: invokevirtual #23; //Method java/lang/invoke/MethodHandle.invokeExact:(Ljava/lang/String;CC)Ljava/lang/String;
mh = lookup.findVirtual(String.class, "replace", mt); s = (String) mh.invokeExact("daddy",'d','n');
InterpreterInterpreter StubQueue 0xfab8_stub_buffer 0x60300-0x74300_buffer_size 0x14000 _buffer_limit 0x14000_number_of_stubs 265
InterpreterCodelets in StubQueuesafept
addr size safe bytecode desc0x00060300 96 0 255/0xff error exits0x00060360 816 0 255/0xff bytecode tracing support0x00060690 1312 0 255/0xff return entry points0x00060bb0 6640 0 255/0xff deoptimization entry points0x000625a0 288 0 255/0xff result handlers for native calls0x000626c0 176 0 255/0xff slow signature handler0x00062770 160 0 255/0xff continuation entry points0x00062810 800 0 255/0xff safepoint entry points0x00062b30 1312 0 255/0xff exception handling0x00063050 704 1 255/0xff throw exception entrypoints0x00063310 640 0 255/0xff method entry point (kind = zerolocals)0x00063590 1024 0 255/0xff method entry point (kind = zerolocals_synchronized)0x00063990 672 0 255/0xff method entry point (kind = empty)0x00063c30 736 0 255/0xff method entry point (kind = accessor)0x00063f10 160 0 255/0xff method entry point (kind = abstract)0x00063fb0 640 0 255/0xff method entry point (kind = java_lang_math_sin)0x00064230 640 0 255/0xff method entry point (kind = java_lang_math_cos)0x000644b0 640 0 255/0xff method entry point (kind = java_lang_math_sqrt)
Interpreter0x00064730 1232 0 255/0xff method entry point (kind = native)0x00064c00 2096 0 255/0xff method entry point (kind = native_synchronized)0x00065430 80 1 0/0x00 #nop0x00065480 80 1 1/0x01 #aconst_null0x000654d0 80 1 2/0x02 #iconst_m1:0x00065660 80 1 7/0x07 #iconst_4:
0x000659e0 176 1 18/0x12 #ldc0x00065a90 176 1 19/0x13 #ldc_w0x00065b40 176 1 20/0x14 #ldc2_w0x00065bf0 128 1 21/0x15 #iload:0x000693b0 112 1 168/0xa8 #jsr0x00069420 192 1 169/0xa9 #ret0x000694e0 96 1 170/0xaa #tableswitch0x00069540 64 1 171/0xab #lookupswitch0x00069580 848 0 172/0xac #ireturn0x000698d0 864 0 173/0xad #lreturn
0x0006b310 32 1 191/0xbf #athrow0x0006b330 240 1 192/0xc0 #checkcast0x0006b420 224 1 193/0xc1 #instanceof0x0006b500 512 1 194/0xc2 #monitorenter0x0006b700 560 1 195/0xc3 #monitorexit0x0006b930 64 1 196/0xc4 #wide
Interpreter_entry_table contents[ 0 zerolocals ] = 0x63320[ 1 zerolocals_synchronized ] = 0x635a0[ 2 native ] = 0x64740[ 3 native_synchronized ] = 0x64c10[ 4 empty ] = 0x639a0[ 5 accessor ] = 0x63c40[ 6 abstract ] = 0x63f20[ 7 java_lang_math_sin ] = 0x63fc0[ 8 java_lang_math_cos ] = 0x64240[ 9 java_lang_math_sqrt ] = 0x644c0
0x00063310 640 0 255/0xff method entry point (kind = zerolocals)0x00063590 1024 0 255/0xff method entry point (kind = zerolocals_synchronized)0x00063990 672 0 255/0xff method entry point (kind = empty)0x00063c30 736 0 255/0xff method entry point (kind = accessor)0x00063f10 160 0 255/0xff method entry point (kind = abstract)
CodeCache::_haap 0x6ffbbde0_number_of_blobs 36_number_of_nmethods_with_dependencies 0
0x6ffbbde0: CodeHeap {0x6ffbbde0: VirtualSpace _memory {0x6ffbbde0: char* _low_boundary; 0x6dc000000x6ffbbde4: char* _high_boundary; 0x6fc000000x6ffbbde8: char* _low; 0x6dc000000x6ffbbdec: char* _high; 0x6dc280000x6ffbbdf0: u1 _low_to_high; 0x010x6ffbbdf0: }0x6ffbbdf4: VirtualSpace _segmap {0x6ffbbdf4: char* _low_boundary; 0x6fe1e0000x6ffbbdf8: char* _high_boundary; 0x6fe9e0000x6ffbbdfc: char* _low; 0x6fe1e0000x6ffbbe00: char* _high; 0x6fe1f0000x6ffbbe04: u1 _low_to_high; 0x010x6ffbbe04: }0x6ffbbe08: int _number_of_committed_segments; 0x00000a000x6ffbbe0c: int _number_of_reserved_segments; 0x000800000x6ffbbe10: int _segment_size; 0x000000400x6ffbbe14: int _log2_segment_size; 0x000000060x6ffbbe18: int _next_segment; 0x000001440x6ffbbe1c: FreeBlock* _freelist; 0x000000000x6ffbbe20: int _free_segments; 0x000000000x6ffbbe20: }HeapBlock 0x6dc00000 _length 8 _used 10x6dc00010: vtbl 0x6ff57d680x6dc00014: CodeBlob {0x6dc00014: int _size; 0x000001c80x6dc00018: int _header_size; 0x000000300x6dc0001c: int _relocation_size; 0x000000140x6dc00020: int _instructions_offset; 0x000000500x6dc00024: int _data_offset; 0x000001c80x6dc00028: int _oops_offset; 0x000001c80x6dc0002c: int _oops_length; 0x000000000x6dc00030: int _frame_size; 0x000000300x6dc00034: int _return_address_offset; 0xffffffca0x6dc00038: int _link_offset; 0xfffffffe0x6dc0003c: OopMapSet* _oop_maps; 0x000175480x6dc0003c: }
0x6dc00060: stw %ret0,0xd0(%r3)0x6dc00064: depwi 0,31,2,%ret10x6dc00068: stw %ret1,0xd4(%r3)0x6dc0006c: stw %ret1,-0x18(%sp)0x6dc00070: copy %sp,%ret10x6dc00074: ldo 0xc0(%sp),%sp0x6dc00078: fstd,ma %fr12,8(%ret1)0x6dc0007c: fstd,ma %fr13,8(%ret1)0x6dc00080: fstd,ma %fr14,8(%ret1)0x6dc00084: fstd,ma %fr15,8(%ret1)0x6dc00088: fstd,ma %fr16,8(%ret1)0x6dc0008c: fstd,ma %fr17,8(%ret1)0x6dc00090: fstd,ma %fr18,8(%ret1)0x6dc00094: ldo -0x38(%ret1),%ret10x6dc00098: stw %r4,0x38(%ret1)0x6dc0009c: stw %r5,0x3c(%ret1)0x6dc000a0: stw %r6,0x40(%ret1)•0x6dc001b0: ldo 0x7a4(%r19),%r190x6dc001b4: bv,n %r0(%r19)0x6dc001b8: ldil L'0x6dc04000,%r200x6dc001bc: ldo 0x7a0(%r20),%r200x6dc001c0: cmpb,<>,n %ret1,%r20,0x6dc001cc0x6dc001c4: ldil L'0x6dc04000,%r190x6dc001c8: ldo 0x7a4(%r19),%r190x6dc001cc: ldw 0xd0(%r3),%ret00x6dc001d0: bv,n %r0(%r19)0x6dc001d4: nop0x6dc001d8: break 0,00x6dc001dc: break 0,0
Hotspot Compiler
Virtual Machine Startup
AbstractInterpreterInterpreter StubQueue 0x8094398
_stub_buffer 0xb1af64c0-0xb1b1f4c0
_buffer_size 0x29000
_buffer_limit 0x29000
_number_of_stubs 0xf8
0xb1af64c0 96 false -1/0x-1 error exits
0xb1af6520 3488 false -1/0x-1 return entry points
0xb1af72c0 13120 false -1/0x-1 deoptimization entry points
0xb1afa600 96 false -1/0x-1 result handlers for native calls
0xb1afa660 160 false -1/0x-1 slow signature handler
0xb1afa700 128 false -1/0x-1 continuation entry points
0xb1afa780 1056 false -1/0x-1 safepoint entry points
0xb1afaba0 2272 false -1/0x-1 exception handling
0xb1afb480 896 true -1/0x-1 throw exception entrypoints
0xb1afb800 896 false -1/0x-1 method entry point (kind = zerolocals)
0xb1afbb80 1056 false -1/0x-1 method entry point (kind =
zerolocals_synchronized)
0xb1afbfa0 64 false -1/0x-1 method entry point (kind = empty)
0xb1afbfe0 1024 false -1/0x-1 method entry point (kind = accessor)
0xb1afc3e0 160 false -1/0x-1 method entry point (kind = abstract)
0xb1afc480 96 false -1/0x-1 method entry point (kind = java_lang_math_sin)
0xb1afc4e0 96 false -1/0x-1 method entry point (kind = java_lang_math_cos)
0xb1afc540 64 false -1/0x-1 method entry point (kind = java_lang_math_sqrt)
0xb1afc580 1728 false -1/0x-1 method entry point (kind = native)
0xb1afcc40 1920 false -1/0x-1 method entry point (kind =
native_synchronized)
0xb1afd3c0 96 true 0/0x00 nop
0xb1afd420 96 true 1/0x01 aconst_null
0xb1afd480 96 true 2/0x02 iconst_m1
0xb1afd4e0 96 true 3/0x03 iconst_0
0xb1afd540 96 true 4/0x04 iconst_1
Virtual Machine Startup
Interpreter bytecode codelet0xb1aff760 64 true 96/0x60 iadd
disas 0xb1aff770 0xb1aff79f
Dump of assembler code from 0xb1aff770 to 0xb1aff79f:
0xb1aff770: add %al,(%eax)
...
0xb1aff780: pop %eax
0xb1aff781: pop %edx
0xb1aff782: add %edx,%eax
0xb1aff784: movzbl 0x1(%esi),%ebx
0xb1aff788: inc %esi
0xb1aff789: jmp *-0x48f8b1a0(,%ebx,4)
0xb1aff790: add %al,(%eax)
0xb1aff792: add %al,(%eax)
0xb1afd540 96 true 4/0x04 iconst_1
disas 0xb1afd550 0xb1afd59f
Dump of assembler code from 0xb1afd550 to 0xb1afd59f:
0xb1afd550: add %al,(%eax)
:
0xb1afd560: sub $0x4,%esp ; sp -= 4
0xb1afd563: fstps (%esp)
0xb1afd566: jmp 0xb1afd578
0xb1afd56b: sub $0x8,%esp
0xb1afd56e: fstpl (%esp)
0xb1afd571: jmp 0xb1afd578
0xb1afd576: push %edx
0xb1afd577: push %eax
0xb1afd578: mov $0x1,%eax ; constant 1
0xb1afd57d: movzbl 0x1(%esi),%ebx ; move next bytecode
0xb1afd581: inc %esi ; advance bcp
0xb1afd582: jmp *-0x48f8b1a0(,%ebx,4) ; 0xb7074e60(,%ebx,4)
Virtual Machine Startup
Interpreter bytecode codelet0xb1afd4e0 96 true 3/0x03 iconst_0
disas 0xb1afd4f0 0xb1afd53f
Dump of assembler code from 0xb1afd4f0 to 0xb1afd53f:
0xb1afd4f0: add %al,(%eax)
0xb1afd4f2: add %al,(%eax)
0xb1afd4f4: add %al,(%eax)
0xb1afd4f6: add %al,(%eax)
0xb1afd4f8: add %al,(%eax)
0xb1afd4fa: add %al,(%eax)
0xb1afd4fc: add %al,(%eax)
0xb1afd4fe: add %al,(%eax)
0xb1afd500: sub $0x4,%esp
0xb1afd503: fstps (%esp)
0xb1afd506: jmp 0xb1afd518
0xb1afd50b: sub $0x8,%esp
0xb1afd50e: fstpl (%esp)
0xb1afd511: jmp 0xb1afd518
0xb1afd516: push %edx
0xb1afd517: push %eax
0xb1afd518: xor %eax,%eax
0xb1afd51a: movzbl 0x1(%esi),%ebx
0xb1afd51e: inc %esi
0xb1afd51f: jmp *-0x48f8b1a0(,%ebx,4)
0xb1afd526: nop
0xb1afd527: nop
0xb1afd528: add %al,(%eax)
Virtual Machine Startup
Interpreter bytecode codelet invokevirtual0xb1b04040 448 false 182/0xb6 invokevirtual
disas 0xb1b04050 0xb1b041ff
Dump of assembler code from 0xb1b04050 to 0xb1b041ff:
0xb1b04050: add %al,(%eax)
0xb1b04052: add %al,(%eax)
0xb1b04054: add %al,(%eax)
0xb1b04056: add %al,(%eax)
0xb1b04058: add %al,(%eax)
0xb1b0405a: add %al,(%eax)
0xb1b0405c: add %al,(%eax)
0xb1b0405e: add %al,(%eax)
0xb1b04060: sub $0x4,%esp
0xb1b04063: fstps (%esp)
0xb1b04066: jmp 0xb1b04078
0xb1b0406b: sub $0x8,%esp
0xb1b0406e: fstpl (%esp)
0xb1b04071: jmp 0xb1b04078
0xb1b04076: push %edx
0xb1b04077: push %eax
0xb1b04078: mov %esi,-0x18(%ebp)
0xb1b0407b: movzwl 0x1(%esi),%edx
// get cache and index at bcp
0xb1b0407f: mov -0x10(%ebp),%ecx
0xb1b04082: shl $0x2,%edx
// resolve cache and index
0xb1b04085: mov 0x10(%ecx,%edx,4),%ebx
0xb1b04089: shr $0x18,%ebx
0xb1b0408c: and $0xff,%ebx
0xb1b04092: cmp $0xb6,%ebx
0xb1b04098: je 0xb1b04112
...
0xb1b04193: jne 0xb1b041a6
0xb1b04199: addl $0x1,0x14(%edi)
0xb1b0419d: sbbl $0x0,0x14(%edi)
0xb1b041a1: jmp 0xb1b041da
0xb1b041a6: xor %edx,%edx
0xb1b041a8: cmp 0x8(%edi),%edx
0xb1b041ab: jne 0xb1b041c1
0xb1b041b1: mov %eax,0x8(%edi)
0xb1b041b4: mov $0x1,%edx
0xb1b041b9: mov %edx,0xc(%edi)
0xb1b041bc: jmp 0xb1b041da
0xb1b041c1: cmp 0x10(%edi),%edx
0xb1b041c4: jne 0xb1b041da
0xb1b041ca: mov %eax,0x10(%edi)
0xb1b041cd: mov $0x1,%edx
0xb1b041d2: mov %edx,0x14(%edi)
0xb1b041d5: jmp 0xb1b041da
0xb1b041da: add $0x18,%edi
0xb1b041dd: mov %edi,-0xc(%ebp)
0xb1b041e0: mov 0x118(%eax,%ebx,4),%ebx
0xb1b041e7: mov 0x3c(%ebx),%edx
0xb1b041ea: mov %ebx,%eax
0xb1b041ec: jmp *%edx ; ->
_entry_table[method_kind(m)];
0xb1b041ee: nop
Virtual Machine Startup
Interpreter bytecode codelet/method entry0xb1afb800 896 false -1/0x-1 method entry point
(kind = zerolocals)
disas 0xb1afb810 0xb1afbb7f
Dump of assembler code from 0xb1afb810 to 0xb1afbb7f:
0xb1afb810: add %al,(%eax)
0xb1afb812: add %al,(%eax)
0xb1afb814: add %al,(%eax)
0xb1afb816: add %al,(%eax)
0xb1afb818: add %al,(%eax)
0xb1afb81a: add %al,(%eax)
0xb1afb81c: add %al,(%eax)
0xb1afb81e: add %al,(%eax)
0xb1afb820: mov 0x38(%ebx),%edx ; _code
0xb1afb823: test %edx,%edx ;
0xb1afb825: jne 0xb1afbae2 ; run compiled
code
0xb1afb82b: movzwl 0x26(%ebx),%ecx
0xb1afb82f: movzwl 0x24(%ebx),%edx
...
run compiled code:
0xb1afbae2: mov %esp,%eax
0xb1afbae4: shr $0xc,%eax
0xb1afbae7: mov -0x48f7eae0(,%eax,4),%eax ; get
thread to eax
0xb1afbaee: movl $0x0,0x108(%eax)
0xb1afbaf8: mov 0x70(%edx),%eax ; interpreter
entry point of the nmethod
0xb1afbafb: test %eax,%eax ; make sure
there is an interpreter entry point
0xb1afbafd: jne 0xb1afbb65
...
0xb1afbb4f: jne 0xb1af4140
0xb1afbb55: mov 0xd4(%edi),%ebx
0xb1afbb5b: movl $0x0,0xd4(%edi)
0xb1afbb65: mov %eax,%edx
0xb1afbb67: mov %ebx,%eax ;
0xb1afbb69: jmp *%edx // to new method
0xb1afbb6b: nop
HotSpot JVM Big Picture
Virtual Machine Startup
Object Synchronizationmonitorenter bytecode の実行、または synchronized method が実行されるとBasicObjectLock がスタック上に割り当てられ、オリジナルの mark と oop がコピーされる. オブジェクトの _mark は BasicObjectLock をさすようになり、下位2ビットは0となる。
オブジェクトが unlock されるとオリジナルのヘッダがリストアされる. BasicObjectLockの oop field がクリアされる.
もし、ロックが開放される前に他のスレッドが同じものをロックしようとすると、_mark フィールドの下位2ビットからすでにロックされていることが分かる.その場合には ObjectMonitor をアロケートして、oopDesc _mark の下位2ビットを 10,そして、残りのビットでObjectMonitor をポイントするようにする。これは inflate 処理と呼ばれる.
ObjectMonitor は queue を持ち、ロックが欲しいスレッドは ObjectWaiter をキューイングしてまつ。
GC 時に inflate されたロックで、GC 時にはロックされていないようなものはdeflate される。
HotSpot JVM Big Picture
Hotspot Compiler
SSA IR : Sea of Nodes