前言
接着前两篇
本文调试一下以下的几个场景
1. 偏向锁的重入
2. 线程1添加了偏向锁并释放, 线程2来获取锁
以下内容基于 jdk9 + lldb-1001.0.13.3
另外以下运行时数据可能是来自于多次调试, 可能会存在运行时数据对不上的情况, 但是条理逻辑会在文字中描述清楚的
偏向锁重入的测试用例
package com.hx.test04;
/**
* Test26SynchronizeReentrantObject
*
* @author Jerry.X.He <970655147@qq.com>
* @version 1.0
* @date 2020-04-03 15:14
*/
public class Test26SynchronizeReentrantObject implements Cloneable {
// identStr
private String identStr = "xyz";
int f01;
int f02;
int f03;
int f04;
int f05;
// Test26SynchronizeReentrantObject
public static void main(String[] args) throws Exception {
Test26SynchronizeReentrantObject lockObj = new Test26SynchronizeReentrantObject();
synchronized (lockObj) {
synchronized (lockObj) {
// Test26SynchronizeReentrantObject cloned = (Test26SynchronizeReentrantObject) lockObj.clone();
// System.out.println(lockObj.identStr);
}
}
}
}
对应的字节码信息如下, 下面参照可能需要使用到
master:classes jerry$ javap -c com/hx/test04/Test26SynchronizeReentrantObject.class
Compiled from "Test26SynchronizeReentrantObject.java"
public class com.hx.test04.Test26SynchronizeReentrantObject implements java.lang.Cloneable {
int f01;
int f02;
int f03;
int f04;
int f05;
public com.hx.test04.Test26SynchronizeReentrantObject();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #2 // String xyz
7: putfield #3 // Field identStr:Ljava/lang/String;
10: return
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: new #4 // class com/hx/test04/Test26SynchronizeReentrantObject
3: dup
4: invokespecial #5 // Method "<init>":()V
7: astore_1
8: aload_1
9: dup
10: astore_2
11: monitorenter
12: aload_1
13: dup
14: astore_3
15: monitorenter
16: aload_3
17: monitorexit
18: goto 28
21: astore 4
23: aload_3
24: monitorexit
25: aload 4
27: athrow
28: aload_2
29: monitorexit
30: goto 40
33: astore 5
35: aload_2
36: monitorexit
37: aload 5
39: athrow
40: return
Exception table:
from to target type
16 18 21 any
21 25 21 any
12 30 33 any
33 37 33 any
}
进入lldb的调试
同样的配方同样的味道, 这里就不在输出 一些 定位一下当前方法 的日志了, 直接进入 正题
(lldb) p _active_table._table[9][194]
(address) $0 = 0x000000010524f980 "XH;"
(lldb) b 0x000000010524f980
Breakpoint 3: address = 0x000000010524f980
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 3.1
frame #0: 0x000000010524f980
-> 0x10524f980: popq %rax
0x10524f981: cmpq (%rax), %rax
0x10524f984: xorl %esi, %esi
0x10524f986: movq -0x48(%rbp), %rcx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
rax = 0x0000000747bb8798
rbx = 0x00000000000000c2
rcx = 0x0000000000000008
rdx = 0x0000000747bb87b8
rdi = 0x0000000101806000
rsi = 0x000070000ba375c0
rbp = 0x000070000ba37670
rsp = 0x000070000ba37620
r8 = 0x0000000000000000
r9 = 0x0000000000000020
r10 = 0x0000000104b0b270 libjvm.dylib`TemplateInterpreter::_active_table + 18432
r11 = 0x00006fff0a229200
r12 = 0x0000000000000000
r13 = 0x000000011d1eff93
r14 = 0x000070000ba376a8
r15 = 0x0000000101806000
rip = 0x000000010524f980
rflags = 0x0000000000000206
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
(lldb) p ((oopDesc*)0x0000000747bb8798)->print()
com.hx.test04.Test26SynchronizeReentrantObject
{0x0000000747bb8798} - klass: 'com/hx/test04/Test26SynchronizeReentrantObject'
- ---- fields (total size 5 words):
- 'f01' 'I' @12 0
- 'f02' 'I' @16 0
- 'f03' 'I' @20 0
- 'f04' 'I' @24 0
- 'f05' 'I' @28 0
- private 'identStr' 'Ljava/lang/String;' @32 "xyz"{0x0000000747bb87c0} (e8f770f8 0)
(lldb) x 0x0000000747bb8798
0x747bb8798: 05 00 00 00 00 00 00 00 86 1f 01 f8 00 00 00 00 ...........?....
0x747bb87a8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
(lldb) x 0x000070000ba37620 -c 0x100
0x70000ba37620: 98 87 bb 47 07 00 00 00 28 76 a3 0b 00 70 00 00 ..?G....(v?..p..
0x70000ba37630: 8c ff 1e 1d 01 00 00 00 a8 76 a3 0b 00 70 00 00 .?......?v?..p..
0x70000ba37640: 88 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba37650: 70 82 bb 47 07 00 00 00 00 00 1f 1d 01 00 00 00 p.?G............
0x70000ba37660: 00 00 00 00 00 00 00 00 a8 76 a3 0b 00 70 00 00 ........?v?..p..
0x70000ba37670: 10 77 a3 0b 00 70 00 00 f1 09 20 05 01 00 00 00 .w?..p..?. .....
0x70000ba37680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba37690: 00 00 00 00 00 00 00 00 98 87 bb 47 07 00 00 00 ..........?G....
0x70000ba376a0: 98 87 bb 47 07 00 00 00 88 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba376b0: a0 1f 00 00 03 00 00 00 00 00 00 00 00 00 00 00 ?...............
0x70000ba376c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba376d0: 00 00 00 00 00 00 00 00 00 80 a3 0b 00 70 00 00 ..........?..p..
0x70000ba376e0: 20 78 a3 0b 00 70 00 00 50 7d a3 0b 00 70 00 00 x?..p..P}?..p..
0x70000ba376f0: 0a 00 00 00 00 70 00 00 00 00 1f 1d 01 00 00 00 .....p..........
0x70000ba37700: 00 a7 22 05 01 00 00 00 a0 7a a3 0b 00 70 00 00 .?".....?z?..p..
0x70000ba37710: e0 78 a3 0b 00 70 00 00 1d bb 0e 04 01 00 00 00 ?x?..p...?......
// continue, 之后 断点停留在了 第二个 monitorenter
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 3.1
frame #0: 0x000000010524f980
-> 0x10524f980: popq %rax
0x10524f981: cmpq (%rax), %rax
0x10524f984: xorl %esi, %esi
0x10524f986: movq -0x48(%rbp), %rcx
Target 0: (java) stopped.
(lldb) p ((oopDesc*)0x0000000747bb8798)->print()
com.hx.test04.Test26SynchronizeReentrantObject
{0x0000000747bb8798} - klass: 'com/hx/test04/Test26SynchronizeReentrantObject'
- ---- fields (total size 5 words):
- 'f01' 'I' @12 0
- 'f02' 'I' @16 0
- 'f03' 'I' @20 0
- 'f04' 'I' @24 0
- 'f05' 'I' @28 0
- private 'identStr' 'Ljava/lang/String;' @32 "xyz"{0x0000000747bb87c0} (e8f770f8 0)
(lldb) p ((oopDesc*)0x0000000747bb8798)->mark()->biased_locker()->threadObj()->print()
java.lang.Thread
{0x0000000747f069d8} - klass: 'java/lang/Thread'
- ---- fields (total size 47 words):
- private 'priority' 'I' @12 5
- private 'eetop' 'J' @16 4320157696 (1806000 1)
- private 'stackSize' 'J' @24 0 (0 0)
- private 'nativeParkEventPointer' 'J' @32 0 (0 0)
- private 'tid' 'J' @40 1 (1 0)
- private volatile 'threadStatus' 'I' @48 5
- private 'single_step' 'Z' @52 false
- private 'daemon' 'Z' @53 false
- private 'stillborn' 'Z' @54 false
- private volatile 'name' 'Ljava/lang/String;' @56 "main"{0x0000000747f06b50} (e8fe0d6a 0)
- private 'threadQ' 'Ljava/lang/Thread;' @60 NULL (0 0)
- private 'target' 'Ljava/lang/Runnable;' @64 NULL (0 e8fe0c85)
- private 'group' 'Ljava/lang/ThreadGroup;' @68 a 'java/lang/ThreadGroup'{0x0000000747f06428} (e8fe0c85 e8fc0af7)
- private 'contextClassLoader' 'Ljava/lang/ClassLoader;' @72 a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x0000000747e057b8} (e8fc0af7 e8fe0d91)
- private 'inheritedAccessControlContext' 'Ljava/security/AccessControlContext;' @76 a 'java/security/AccessControlContext'{0x0000000747f06c88} (e8fe0d91 e8fe2fb8)
- 'threadLocals' 'Ljava/lang/ThreadLocal$ThreadLocalMap;' @80 a 'java/lang/ThreadLocal$ThreadLocalMap'{0x0000000747f17dc0} (e8fe2fb8 0)
- 'inheritableThreadLocals' 'Ljava/lang/ThreadLocal$ThreadLocalMap;' @84 NULL (0 0)
- volatile 'parkBlocker' 'Ljava/lang/Object;' @88 NULL (0 0)
- private volatile 'blocker' 'Lsun/nio/ch/Interruptible;' @92 NULL (0 e8fe0d70)
- private final 'blockerLock' 'Ljava/lang/Object;' @96 a 'java/lang/Object'{0x0000000747f06b80} (e8fe0d70 0)
- private volatile 'uncaughtExceptionHandler' 'Ljava/lang/Thread$UncaughtExceptionHandler;' @100 NULL (0 0)
- 'threadLocalRandomSeed' 'J' @232 0 (0 0)
- 'threadLocalRandomProbe' 'I' @240 0
- 'threadLocalRandomSecondarySeed' 'I' @244 0
(lldb) x 0x0000000747bb8798
0x747bb8798: 05 60 80 01 01 00 00 00 86 1f 01 f8 00 00 00 00 .`.........?....
0x747bb87a8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
(lldb) re r
General Purpose Registers:
rax = 0x0000000747bb8798
rbx = 0x00000000000000c2
rcx = 0x0000000747bb8798
rdx = 0x000070000ba37628
rdi = 0x0000000101806000
rsi = 0x000070000ba37618
rbp = 0x000070000ba37670
rsp = 0x000070000ba37610
r8 = 0x0000000000000000
r9 = 0x0000000000000020
r10 = 0x0000000104b0b270 libjvm.dylib`TemplateInterpreter::_active_table + 18432
r11 = 0x00006fff0a229200
r12 = 0x0000000000000000
r13 = 0x000000011d1eff97
r14 = 0x000070000ba376a8
r15 = 0x0000000101806000
rip = 0x000000010524f980
rflags = 0x0000000000000202
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
(lldb) x 0x000070000ba37610 -c 0x100
0x70000ba37610: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba37620: 98 87 bb 47 07 00 00 00 18 76 a3 0b 00 70 00 00 ..?G.....v?..p..
0x70000ba37630: 94 ff 1e 1d 01 00 00 00 a8 76 a3 0b 00 70 00 00 .?......?v?..p..
0x70000ba37640: 88 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba37650: 70 82 bb 47 07 00 00 00 00 00 1f 1d 01 00 00 00 p.?G............
0x70000ba37660: 00 00 00 00 00 00 00 00 a8 76 a3 0b 00 70 00 00 ........?v?..p..
0x70000ba37670: 10 77 a3 0b 00 70 00 00 f1 09 20 05 01 00 00 00 .w?..p..?. .....
0x70000ba37680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba37690: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba376a0: 98 87 bb 47 07 00 00 00 88 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba376b0: a0 1f 00 00 03 00 00 00 00 00 00 00 00 00 00 00 ?...............
0x70000ba376c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba376d0: 00 00 00 00 00 00 00 00 00 80 a3 0b 00 70 00 00 ..........?..p..
0x70000ba376e0: 20 78 a3 0b 00 70 00 00 50 7d a3 0b 00 70 00 00 x?..p..P}?..p..
0x70000ba376f0: 0a 00 00 00 00 70 00 00 00 00 1f 1d 01 00 00 00 .....p..........
0x70000ba37700: 00 a7 22 05 01 00 00 00 a0 7a a3 0b 00 70 00 00 .?".....?z?..p..
这里在 monitorenter 的地方打了一个断点, 并且输出了 当前 lockObj 的相关信息之后, 直接 continue, 断点停在了 第二个 monitorenter
我们可以整理一些结论
1. 在第一个断点的时候, lockObj 没有锁, 就一个 0x101, 第二个断点的时候 已经加上了偏向锁 偏向于 main 线程
2. 第二个断点相比于 第一个断点, [0x70000ba37618 - 0x70000ba37628) 增加了一个 BasicLockObject 关联 lockObj 对象
那么 我们接下来看一下 重入的情况 会走怎么样的流程呢
分配了 BasicObjectLock 之后情况如下
(lldb) b 0x10524f9dc
Breakpoint 4: address = 0x000000010524f9dc
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 4.1
frame #0: 0x000000010524f9dc
-> 0x10524f9dc: incq %r13
0x10524f9df: movq %rax, 0x8(%rsi)
0x10524f9e3: movq 0x8(%rsi), %rcx
0x10524f9e7: movq (%rcx), %rax
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
rax = 0x0000000747bb8798
rbx = 0x00000000000000c2
rcx = 0x000070000ba37608
rdx = 0x000070000ba37628
rdi = 0x0000000101806000
rsi = 0x000070000ba37608
rbp = 0x000070000ba37670
rsp = 0x000070000ba37608
r8 = 0x0000000000000000
r9 = 0x0000000000000020
r10 = 0x0000000104b0b270 libjvm.dylib`TemplateInterpreter::_active_table + 18432
r11 = 0x00006fff0a229200
r12 = 0x0000000000000000
r13 = 0x000000011d1eff97
r14 = 0x000070000ba376a8
r15 = 0x0000000101806000
rip = 0x000000010524f9dc
rflags = 0x0000000000000246
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
(lldb) x 0x000070000ba37608 -c 0x100
0x70000ba37608: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba37618: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba37628: 08 76 a3 0b 00 70 00 00 94 ff 1e 1d 01 00 00 00 .v?..p...?......
0x70000ba37638: a8 76 a3 0b 00 70 00 00 88 00 1f 1d 01 00 00 00 ?v?..p..........
0x70000ba37648: 00 00 00 00 00 00 00 00 70 82 bb 47 07 00 00 00 ........p.?G....
0x70000ba37658: 00 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba37668: a8 76 a3 0b 00 70 00 00 10 77 a3 0b 00 70 00 00 ?v?..p...w?..p..
0x70000ba37678: f1 09 20 05 01 00 00 00 00 00 00 00 00 00 00 00 ?. .............
0x70000ba37688: 00 00 00 00 00 00 00 00 98 87 bb 47 07 00 00 00 ..........?G....
0x70000ba37698: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba376a8: 88 87 bb 47 07 00 00 00 a0 1f 00 00 03 00 00 00 ..?G....?.......
0x70000ba376b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba376c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba376d8: 00 80 a3 0b 00 70 00 00 20 78 a3 0b 00 70 00 00 ..?..p.. x?..p..
0x70000ba376e8: 50 7d a3 0b 00 70 00 00 0a 00 00 00 00 70 00 00 P}?..p.......p..
0x70000ba376f8: 00 00 1f 1d 01 00 00 00 00 a7 22 05 01 00 00 00 .........?".....
0x70000ba37628 : 标记点的是 expression bottom, 第二次 monitorenter 的时候是 0x000070000ba37618
现在有多了一个 BasicLockObject 了, 变成了 0x000070000ba37608
加锁的流程如下
(lldb) stepi -c 7
Process 2762 stopped
* thread #5, stop reason = instruction step into
frame #0: 0x000000010524f9f5
-> 0x10524f9f5: jne 0x10524fa7c
0x10524f9fb: movl 0x8(%rcx), %ebx
0x10524f9fe: shlq $0x3, %rbx
0x10524fa02: movq 0xb0(%rbx), %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
frame #0: 0x000000010524f9fb
-> 0x10524f9fb: movl 0x8(%rcx), %ebx
0x10524f9fe: shlq $0x3, %rbx
0x10524fa02: movq 0xb0(%rbx), %rbx
0x10524fa09: orq %r15, %rbx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
rax = 0x0000000101806005
rbx = 0x0000000000000005
rcx = 0x0000000747bb8798
rdx = 0x000070000ba37628
rdi = 0x0000000101806000
rsi = 0x000070000ba37608
rbp = 0x000070000ba37670
rsp = 0x000070000ba37608
r8 = 0x0000000000000000
r9 = 0x0000000000000020
r10 = 0x0000000104b0b270 libjvm.dylib`TemplateInterpreter::_active_table + 18432
r11 = 0x00006fff0a229200
r12 = 0x0000000000000000
r13 = 0x000000011d1eff98
r14 = 0x000070000ba376a8
r15 = 0x0000000101806000
rip = 0x000000010524f9fb
rflags = 0x0000000000000246
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
frame #0: 0x000000010524f9fe
-> 0x10524f9fe: shlq $0x3, %rbx
0x10524fa02: movq 0xb0(%rbx), %rbx
0x10524fa09: orq %r15, %rbx
0x10524fa0c: xorq %rax, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
frame #0: 0x000000010524fa02
-> 0x10524fa02: movq 0xb0(%rbx), %rbx
0x10524fa09: orq %r15, %rbx
0x10524fa0c: xorq %rax, %rbx
0x10524fa0f: andq $-0x79, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
frame #0: 0x000000010524fa09
-> 0x10524fa09: orq %r15, %rbx
0x10524fa0c: xorq %rax, %rbx
0x10524fa0f: andq $-0x79, %rbx
0x10524fa13: je 0x10524fd05
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
frame #0: 0x000000010524fa0c
-> 0x10524fa0c: xorq %rax, %rbx
0x10524fa0f: andq $-0x79, %rbx
0x10524fa13: je 0x10524fd05
0x10524fa19: testq $0x7, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
frame #0: 0x000000010524fa0f
-> 0x10524fa0f: andq $-0x79, %rbx
0x10524fa13: je 0x10524fd05
0x10524fa19: testq $0x7, %rbx
0x10524fa20: jne 0x10524fa69
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
rax = 0x0000000101806005
rbx = 0x0000000000000000
rcx = 0x0000000747bb8798
rdx = 0x000070000ba37628
rdi = 0x0000000101806000
rsi = 0x000070000ba37608
rbp = 0x000070000ba37670
rsp = 0x000070000ba37608
r8 = 0x0000000000000000
r9 = 0x0000000000000020
r10 = 0x0000000104b0b270 libjvm.dylib`TemplateInterpreter::_active_table + 18432
r11 = 0x00006fff0a229200
r12 = 0x0000000000000000
r13 = 0x000000011d1eff98
r14 = 0x000070000ba376a8
r15 = 0x0000000101806000
rip = 0x000000010524fa0f
rflags = 0x0000000000000246
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
frame #0: 0x000000010524fa13
-> 0x10524fa13: je 0x10524fd05
0x10524fa19: testq $0x7, %rbx
0x10524fa20: jne 0x10524fa69
0x10524fa22: testq $0x300, %rbx ; imm = 0x300
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
frame #0: 0x000000010524fd05
-> 0x10524fd05: movq %r13, -0x40(%rbp)
0x10524fd09: movl %eax, -0x16000(%rsp)
0x10524fd10: movzbl (%r13), %ebx
0x10524fd15: movabsq $0x104b0b270, %r10 ; imm = 0x104B0B270
Target 0: (java) stopped.
发现当前线程 和 偏向锁上面记录的线程, epoch 一样, 直接 加锁完成
偏向锁的退出
(lldb) p _active_table._table[9][195]
(address) $1 = 0x000000010524fde0 "XH;"
(lldb) b 0x000000010524fde1
Breakpoint 5: address = 0x000000010524fde1
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 5.1
frame #0: 0x000000010524fde1
-> 0x10524fde1: cmpq (%rax), %rax
0x10524fde4: movq -0x48(%rbp), %rsi
0x10524fde8: leaq -0x48(%rbp), %rdx
0x10524fdec: jmp 0x10524fdfc
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
rax = 0x0000000747bb8798
rbx = 0x00000000000000c3
rcx = 0x0000000747bb8798
rdx = 0x000070000ba37628
rdi = 0x0000000101806000
rsi = 0x000070000ba37608
rbp = 0x000070000ba37670
rsp = 0x000070000ba37608
r8 = 0x0000000000000000
r9 = 0x0000000000000020
r10 = 0x0000000104b0aa70 libjvm.dylib`TemplateInterpreter::_active_table + 16384
r11 = 0x00006fff0a229200
r12 = 0x0000000000000000
r13 = 0x000000011d1eff99
r14 = 0x000070000ba376a8
r15 = 0x0000000101806000
rip = 0x000000010524fde1
rflags = 0x0000000000000206
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
(lldb) p ((oopDesc*)0x0000000747bb8798)->print()
com.hx.test04.Test26SynchronizeReentrantObject
{0x0000000747bb8798} - klass: 'com/hx/test04/Test26SynchronizeReentrantObject'
- ---- fields (total size 5 words):
- 'f01' 'I' @12 0
- 'f02' 'I' @16 0
- 'f03' 'I' @20 0
- 'f04' 'I' @24 0
- 'f05' 'I' @28 0
- private 'identStr' 'Ljava/lang/String;' @32 "xyz"{0x0000000747bb87c0} (e8f770f8 0)
(lldb) x 0x000070000ba37608 -c 0x100
0x70000ba37608: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba37618: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba37628: 08 76 a3 0b 00 70 00 00 98 ff 1e 1d 01 00 00 00 .v?..p...?......
0x70000ba37638: a8 76 a3 0b 00 70 00 00 88 00 1f 1d 01 00 00 00 ?v?..p..........
0x70000ba37648: 00 00 00 00 00 00 00 00 70 82 bb 47 07 00 00 00 ........p.?G....
0x70000ba37658: 00 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba37668: a8 76 a3 0b 00 70 00 00 10 77 a3 0b 00 70 00 00 ?v?..p...w?..p..
0x70000ba37678: f1 09 20 05 01 00 00 00 00 00 00 00 00 00 00 00 ?. .............
0x70000ba37688: 00 00 00 00 00 00 00 00 98 87 bb 47 07 00 00 00 ..........?G....
0x70000ba37698: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba376a8: 88 87 bb 47 07 00 00 00 a0 1f 00 00 03 00 00 00 ..?G....?.......
0x70000ba376b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba376c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba376d8: 00 80 a3 0b 00 70 00 00 20 78 a3 0b 00 70 00 00 ..?..p.. x?..p..
0x70000ba376e8: 50 7d a3 0b 00 70 00 00 0a 00 00 00 00 70 00 00 P}?..p.......p..
0x70000ba376f8: 00 00 1f 1d 01 00 00 00 00 a7 22 05 01 00 00 00 .........?".....
// continue, 之后 断点停留在了 第二个 monitorexit
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 5.1
frame #0: 0x000000010524fde1
-> 0x10524fde1: cmpq (%rax), %rax
0x10524fde4: movq -0x48(%rbp), %rsi
0x10524fde8: leaq -0x48(%rbp), %rdx
0x10524fdec: jmp 0x10524fdfc
Target 0: (java) stopped.
(lldb) x 0x000070000ba37608 -c 0x100
0x70000ba37608: 98 87 bb 47 07 00 00 00 00 00 00 00 00 00 00 00 ..?G............
0x70000ba37618: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba37628: 08 76 a3 0b 00 70 00 00 99 ff 1e 1d 01 00 00 00 .v?..p...?......
0x70000ba37638: a8 76 a3 0b 00 70 00 00 88 00 1f 1d 01 00 00 00 ?v?..p..........
0x70000ba37648: 00 00 00 00 00 00 00 00 70 82 bb 47 07 00 00 00 ........p.?G....
0x70000ba37658: 00 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba37668: a8 76 a3 0b 00 70 00 00 10 77 a3 0b 00 70 00 00 ?v?..p...w?..p..
0x70000ba37678: f1 09 20 05 01 00 00 00 00 00 00 00 00 00 00 00 ?. .............
0x70000ba37688: 00 00 00 00 00 00 00 00 98 87 bb 47 07 00 00 00 ..........?G....
0x70000ba37698: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba376a8: 88 87 bb 47 07 00 00 00 a0 1f 00 00 03 00 00 00 ..?G....?.......
0x70000ba376b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba376c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba376d8: 00 80 a3 0b 00 70 00 00 20 78 a3 0b 00 70 00 00 ..?..p.. x?..p..
0x70000ba376e8: 50 7d a3 0b 00 70 00 00 0a 00 00 00 00 70 00 00 P}?..p.......p..
0x70000ba376f8: 00 00 1f 1d 01 00 00 00 00 a7 22 05 01 00 00 00 .........?".....
(lldb) b 0x1052500ec
Breakpoint 6: address = 0x00000001052500ec
(lldb) c
Process 2762 resuming
Process 2762 stopped
* thread #5, stop reason = breakpoint 6.1
frame #0: 0x00000001052500ec
-> 0x1052500ec: movq (%rcx), %rdx
0x1052500ef: andq $0x7, %rdx
0x1052500f3: cmpq $0x5, %rdx
0x1052500f7: je 0x105250378
Target 0: (java) stopped.
(lldb) stepi -c 3
Process 2762 stopped
* thread #5, stop reason = instruction step into
frame #0: 0x00000001052500f7
-> 0x1052500f7: je 0x105250378
0x1052500fd: movq (%rax), %rdx
0x105250100: testq %rdx, %rdx
0x105250103: je 0x105250378
Target 0: (java) stopped.
(lldb) stepi
Process 2762 stopped
* thread #5, stop reason = instruction step into
frame #0: 0x0000000105250378
-> 0x105250378: movq -0x40(%rbp), %r13
0x10525037c: popq %rax
0x10525037d: movzbl 0x1(%r13), %ebx
0x105250382: incq %r13
Target 0: (java) stopped.
(lldb) x 0x000070000ba37608 -c 0x100
0x70000ba37608: 98 87 bb 47 07 00 00 00 00 00 00 00 00 00 00 00 ..?G............
0x70000ba37618: 98 87 bb 47 07 00 00 00 00 00 00 00 00 00 00 00 ..?G............
0x70000ba37628: 08 76 a3 0b 00 70 00 00 a5 ff 1e 1d 01 00 00 00 .v?..p..??......
0x70000ba37638: a8 76 a3 0b 00 70 00 00 88 00 1f 1d 01 00 00 00 ?v?..p..........
0x70000ba37648: 00 00 00 00 00 00 00 00 70 82 bb 47 07 00 00 00 ........p.?G....
0x70000ba37658: 00 00 1f 1d 01 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba37668: a8 76 a3 0b 00 70 00 00 10 77 a3 0b 00 70 00 00 ?v?..p...w?..p..
0x70000ba37678: f1 09 20 05 01 00 00 00 00 00 00 00 00 00 00 00 ?. .............
0x70000ba37688: 00 00 00 00 00 00 00 00 98 87 bb 47 07 00 00 00 ..........?G....
0x70000ba37698: 98 87 bb 47 07 00 00 00 98 87 bb 47 07 00 00 00 ..?G......?G....
0x70000ba376a8: 88 87 bb 47 07 00 00 00 a0 1f 00 00 03 00 00 00 ..?G....?.......
0x70000ba376b8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba376c8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x70000ba376d8: 00 80 a3 0b 00 70 00 00 20 78 a3 0b 00 70 00 00 ..?..p.. x?..p..
0x70000ba376e8: 50 7d a3 0b 00 70 00 00 0a 00 00 00 00 70 00 00 P}?..p.......p..
0x70000ba376f8: 00 00 1f 1d 01 00 00 00 00 a7 22 05 01 00 00 00 .........?".....
可以看到这里的两次偏向锁的退出 主要的事情是 吧对应的 BasicLockObject.obj 置空处理(一则是标记obj已经不持有锁了, 二则是其他的对象可以复用)
偏向线程同步块执行完成 非偏向线程尝试加锁
package com.hx.test04;
/**
* Test27MultiThreadInBiasLock
*
* @author Jerry.X.He <970655147@qq.com>
* @version 1.0
* @date 2020-04-03 15:14
*/
public class Test27MultiThreadInBiasLock implements Cloneable {
// identStr
private String identStr = "xyz";
int f01;
int f02;
int f03;
int f04;
int f05;
// Test25SynchronizeObject
public static void main(String[] args) throws Exception {
Test27MultiThreadInBiasLock lockObj = new Test27MultiThreadInBiasLock();
doClone(lockObj);
synchronized (lockObj) {
}
new Thread() {
@Override
public void run() {
doClone(lockObj);
synchronized (lockObj) {
}
}
}.start();
Test25SynchronizeObject.sleep(2000);
}
// doClone
private static void doClone(Test27MultiThreadInBiasLock obj) {
try {
obj.clone();
} catch (Exception e) {
e.printStackTrace();
}
}
}
lldb 调试如下
(lldb) p _active_table._table[9][194]
(address) $0 = 0x000000010584f980 "XH;"
(lldb) c
Process 2916 resuming
Process 2916 stopped
* thread #5, stop reason = breakpoint 3.1
frame #0: 0x0000000103171ab4 libjvm.dylib`::JVM_Clone(env=0x0000000101008a28, handle=0x000070000f2635c8) at jvm.cpp:627:28
624 JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
625 JVMWrapper("JVM_Clone");
626 Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
-> 627 const KlassHandle klass (THREAD, obj->klass());
628 JvmtiVMObjectAllocEventCollector oam;
629
630 #ifdef ASSERT
Target 0: (java) stopped.
(lldb) c
Process 2916 resuming
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = breakpoint 3.1
frame #0: 0x0000000103171ab4 libjvm.dylib`::JVM_Clone(env=0x0000000101054228, handle=0x00007000113c65e0) at jvm.cpp:627:28
624 JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
625 JVMWrapper("JVM_Clone");
626 Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
-> 627 const KlassHandle klass (THREAD, obj->klass());
628 JvmtiVMObjectAllocEventCollector oam;
629
630 #ifdef ASSERT
Target 0: (java) stopped.
(lldb) b 0x000000010584f980
Breakpoint 4: address = 0x000000010584f980
(lldb) c
Process 2916 resuming
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = breakpoint 4.1
frame #0: 0x000000010584f980
-> 0x10584f980: popq %rax
0x10584f981: cmpq (%rax), %rax
0x10584f984: xorl %esi, %esi
0x10584f986: movq -0x48(%rbp), %rcx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
rax = 0x0000000747bb8ec0
rbx = 0x00000000000000c2
rcx = 0x00000000000000cb
rdx = 0x0000000000000000
rdi = 0x000000010580b220
rsi = 0x00007000113c6650
rbp = 0x00007000113c66f8
rsp = 0x00007000113c66a8
r8 = 0x0000000000000000
r9 = 0x0000000100315a90
r10 = 0x0000000103b0b270 libjvm.dylib`TemplateInterpreter::_active_table + 18432
r11 = 0x00007000113c65e0
r12 = 0x0000000000000000
r13 = 0x000000011d46f845
r14 = 0x00007000113c6718
r15 = 0x0000000101054000
rip = 0x000000010584f980
rflags = 0x0000000000000202
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
(lldb) p ((oopDesc*)0x0000000747bb8ec0)->print()
com.hx.test04.Test27MultiThreadInBiasLock
{0x0000000747bb8ec0} - klass: 'com/hx/test04/Test27MultiThreadInBiasLock'
- ---- fields (total size 5 words):
- 'f01' 'I' @12 0
- 'f02' 'I' @16 0
- 'f03' 'I' @20 0
- 'f04' 'I' @24 0
- 'f05' 'I' @28 0
- private 'identStr' 'Ljava/lang/String;' @32 "xyz"{0x0000000747bb8ee8} (e8f771dd 0)
(lldb) p ((oopDesc*)0x0000000747bb8ec0)->mark()->biased_locker()->threadObj()->print()
java.lang.Thread
{0x0000000747f069d8} - klass: 'java/lang/Thread'
- ---- fields (total size 47 words):
- private 'priority' 'I' @12 5
- private 'eetop' 'J' @16 4311779328 (1008800 1)
- private 'stackSize' 'J' @24 0 (0 0)
- private 'nativeParkEventPointer' 'J' @32 0 (0 0)
- private 'tid' 'J' @40 1 (1 0)
- private volatile 'threadStatus' 'I' @48 5
- private 'single_step' 'Z' @52 false
- private 'daemon' 'Z' @53 false
- private 'stillborn' 'Z' @54 false
- private volatile 'name' 'Ljava/lang/String;' @56 "main"{0x0000000747f06b50} (e8fe0d6a 0)
- private 'threadQ' 'Ljava/lang/Thread;' @60 NULL (0 0)
- private 'target' 'Ljava/lang/Runnable;' @64 NULL (0 e8fe0c85)
- private 'group' 'Ljava/lang/ThreadGroup;' @68 a 'java/lang/ThreadGroup'{0x0000000747f06428} (e8fe0c85 e8fc0af7)
- private 'contextClassLoader' 'Ljava/lang/ClassLoader;' @72 a 'jdk/internal/loader/ClassLoaders$AppClassLoader'{0x0000000747e057b8} (e8fc0af7 e8fe0d91)
- private 'inheritedAccessControlContext' 'Ljava/security/AccessControlContext;' @76 a 'java/security/AccessControlContext'{0x0000000747f06c88} (e8fe0d91 e8fe2fb8)
- 'threadLocals' 'Ljava/lang/ThreadLocal$ThreadLocalMap;' @80 a 'java/lang/ThreadLocal$ThreadLocalMap'{0x0000000747f17dc0} (e8fe2fb8 0)
- 'inheritableThreadLocals' 'Ljava/lang/ThreadLocal$ThreadLocalMap;' @84 NULL (0 0)
- volatile 'parkBlocker' 'Ljava/lang/Object;' @88 NULL (0 0)
- private volatile 'blocker' 'Lsun/nio/ch/Interruptible;' @92 NULL (0 e8fe0d70)
- private final 'blockerLock' 'Ljava/lang/Object;' @96 a 'java/lang/Object'{0x0000000747f06b80} (e8fe0d70 0)
- private volatile 'uncaughtExceptionHandler' 'Ljava/lang/Thread$UncaughtExceptionHandler;' @100 NULL (0 0)
- 'threadLocalRandomSeed' 'J' @232 0 (0 0)
- 'threadLocalRandomProbe' 'I' @240 0
- 'threadLocalRandomSecondarySeed' 'I' @244 0
(lldb) b 0x10584f9e3
Breakpoint 5: address = 0x000000010584f9e3
(lldb) c
Process 2916 resuming
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = breakpoint 5.1
frame #0: 0x000000010584f9e3
-> 0x10584f9e3: movq 0x8(%rsi), %rcx
0x10584f9e7: movq (%rcx), %rax
0x10584f9ea: movq %rax, %rbx
0x10584f9ed: andq $0x7, %rbx
Target 0: (java) stopped.
(lldb) stepi -c 4
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584f9f1
-> 0x10584f9f1: cmpq $0x5, %rbx
0x10584f9f5: jne 0x10584fa7c
0x10584f9fb: movl 0x8(%rcx), %ebx
0x10584f9fe: shlq $0x3, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584f9f5
-> 0x10584f9f5: jne 0x10584fa7c
0x10584f9fb: movl 0x8(%rcx), %ebx
0x10584f9fe: shlq $0x3, %rbx
0x10584fa02: movq 0xb0(%rbx), %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584f9fb
-> 0x10584f9fb: movl 0x8(%rcx), %ebx
0x10584f9fe: shlq $0x3, %rbx
0x10584fa02: movq 0xb0(%rbx), %rbx
0x10584fa09: orq %r15, %rbx
Target 0: (java) stopped.
(lldb) stepi -c 4
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa0c
-> 0x10584fa0c: xorq %rax, %rbx
0x10584fa0f: andq $-0x79, %rbx
0x10584fa13: je 0x10584fd05
0x10584fa19: testq $0x7, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa0f
-> 0x10584fa0f: andq $-0x79, %rbx
0x10584fa13: je 0x10584fd05
0x10584fa19: testq $0x7, %rbx
0x10584fa20: jne 0x10584fa69
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa13
-> 0x10584fa13: je 0x10584fd05
0x10584fa19: testq $0x7, %rbx
0x10584fa20: jne 0x10584fa69
0x10584fa22: testq $0x300, %rbx ; imm = 0x300
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa19
-> 0x10584fa19: testq $0x7, %rbx
0x10584fa20: jne 0x10584fa69
0x10584fa22: testq $0x300, %rbx ; imm = 0x300
0x10584fa29: jne 0x10584fa48
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa20
-> 0x10584fa20: jne 0x10584fa69
0x10584fa22: testq $0x300, %rbx ; imm = 0x300
0x10584fa29: jne 0x10584fa48
0x10584fa2b: andq $0x37f, %rax ; imm = 0x37F
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa22
-> 0x10584fa22: testq $0x300, %rbx ; imm = 0x300
0x10584fa29: jne 0x10584fa48
0x10584fa2b: andq $0x37f, %rax ; imm = 0x37F
0x10584fa32: movq %rax, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa29
-> 0x10584fa29: jne 0x10584fa48
0x10584fa2b: andq $0x37f, %rax ; imm = 0x37F
0x10584fa32: movq %rax, %rbx
0x10584fa35: orq %r15, %rbx
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa2b
-> 0x10584fa2b: andq $0x37f, %rax ; imm = 0x37F
0x10584fa32: movq %rax, %rbx
0x10584fa35: orq %r15, %rbx
0x10584fa38: lock
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa32
-> 0x10584fa32: movq %rax, %rbx
0x10584fa35: orq %r15, %rbx
0x10584fa38: lock
0x10584fa39: cmpxchgq %rbx, (%rcx)
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa35
-> 0x10584fa35: orq %r15, %rbx
0x10584fa38: lock
0x10584fa39: cmpxchgq %rbx, (%rcx)
0x10584fa3d: jne 0x10584faa5
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa38
-> 0x10584fa38: lock
0x10584fa39: cmpxchgq %rbx, (%rcx)
0x10584fa3d: jne 0x10584faa5
0x10584fa43: jmp 0x10584fd05
Target 0: (java) stopped.
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584fa3d
-> 0x10584fa3d: jne 0x10584faa5
0x10584fa43: jmp 0x10584fd05
0x10584fa48: movl 0x8(%rcx), %ebx
0x10584fa4b: shlq $0x3, %rbx
Target 0: (java) stopped.
(lldb) re r
General Purpose Registers:
rax = 0x0000000101008805
rbx = 0x0000000101054005
rcx = 0x0000000747bb8ec0
rdx = 0x00007000113c66b0
rdi = 0x000000010580b220
rsi = 0x00007000113c66a0
rbp = 0x00007000113c66f8
rsp = 0x00007000113c66a0
r8 = 0x0000000000000000
r9 = 0x0000000100315a90
r10 = 0x0000000103b0b270 libjvm.dylib`TemplateInterpreter::_active_table + 18432
r11 = 0x00007000113c65e0
r12 = 0x0000000000000000
r13 = 0x000000011d46f846
r14 = 0x00007000113c6718
r15 = 0x0000000101054000
rip = 0x000000010584fa3d
rflags = 0x0000000000000287
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
(lldb) stepi
Process 2916 stopped
* thread #38, name = 'Java: Thread-0', stop reason = instruction step into
frame #0: 0x000000010584faa5
-> 0x10584faa5: callq 0x10584faaf
0x10584faaa: jmp 0x10584fd05
0x10584faaf: leaq 0x8(%rsp), %rax
0x10584fab4: movq %r13, -0x40(%rbp)
Target 0: (java) stopped.
到 monitorenter 的代码的时候, lockObj 的偏向锁已经偏向于 main 线程, 并且 main 线程已经退出了 同步代码块
然后 Thread-0 走同步的流程, 申请 BasicLockObject, 然后创建 走的是 正常更新偏向锁的流程, 但是 由于 lockObj 的偏向锁已经偏向于 main 线程, 因此 cas 更新 mark 的时候失败了, 之后 走的 InterpreterRuntime::monitorenter 的流程
然后 这部分的处理, 在这里 就不展开了
偏向锁可以 偏向线程1 之后 偏向线程2 么?
撤销偏向锁的调用的地方
上面第二行传入 变量的方法, 调用的地方
上面第二行传入 变量的方法, 调用的地方, 可能是 true, 这个方法是 BiasedLocking::revoke_and_rebias
只有在 synchronizer.cpp 里面的 fast_enter 方法里面可能传入true
但是就算是这里传入的是 true, 后面创建了批量Rebias 的 VMOperation, operation 里面返回的状态也是 BiasedLocking::BIAS_REVOKED, 后面还是走锁升级 的处理所以应该是不会出现这种情况, 存在竞争锁会 inflate
完