gpt4 book ai didi

java - 程序丢失一个增量和两个 `` printf``s

转载 作者:行者123 更新时间:2023-11-30 20:20:11 25 4
gpt4 key购买 nike

在下面的方法中,我们设置volatile int success = 0,然后输入a

while(!success) 循环。

循环递增tries,然后进入一个事务,在该事务中我们调用 java sun.misc.Unsafe.putLong 并且一直循环直到事务发生成功。

只要设置了调试标志__TRX_DEBUG__,它就会在返回之前打印尝试次数。

由于该数字始终为零,因此我添加了一些“Hello”printf

程序的输出是

Hello0?!

putLong: (Lsun/misc/Unsafe;Ljava/lang/Class;Ljava/lang/Object;JJ)V with 0 tries

我根本不明白为什么。

/*
* Class: jnirtm_Transactionally
* Method: putLong
* Signature: (Lsun/misc/Unsafe;Ljava/lang/Class;Ljava/lang/Object;JJ)V
*/
jmethodID midPutLong = NULL;
JNIEXPORT void JNICALL Java_jnirtm_Transactionally_putLong__Lsun_misc_Unsafe_2Ljava_lang_Class_2Ljava_lang_Object_2JJ(
JNIEnv *env,
jclass _obsolete,
jobject unsafe,
jclass unsafe_class,
jobject base,
jlong off,
jlong value
){
if(midPutLong == NULL){
midPutLong = (*env)->GetMethodID(env,unsafe_class,"putLong","(Ljava/lang/Object;JJ)V");
#ifdef __TRX_ASSERT__
assert(midPutLong != NULL);
#endif
}

volatile int tries = 0;
volatile int success = 0;
while(!success){/*TODO: maybe switch to a different strategy when tries grows too large?*/
printf("Hello0?!\n");
__asm__ __volatile__ (
"incl %0\n"
"xbegin 1f" /*1f: local label 1, look forward to find first*/
:"+rm"(tries)
:"rm"(success)/*artificial dependency to prevent re-ordering*/
);

/*do we need more artificial dependencies, here, to avoid re-ordering?*/

//unsafe.putInt(base,off,value);
printf("Hello1?!\n");
(*env)-> CallVoidMethod(env,unsafe,midPutLong,base,off,value);
printf("Hello2?!\n");

__asm__ __volatile__ (
"xend\n\t"
"incl %0\n" /*increment success ==> break out of loop*/
"jmp 2f\n" /*jump to end of loop*/
"1:\n" /*local label 1 (jumped to when transaction is aborted)*/
"2:" /*local label 2 (jumped to after a successfully completed transaction)*/
:"+rm"(success)
:"rm"(tries) /*artificial dependency*/
);
}
#ifdef __TRX_DEBUG__
printf("putLong: (Lsun/misc/Unsafe;Ljava/lang/Class;Ljava/lang/Object;JJ)V with %d tries\n",tries);
#endif
}

有趣的是,在文件的更上方,我有一个不同的方法,

/*
* Class: jnirtm_Transactionally
* Method: putLong
* Signature: (Ljava/lang/Object;Ljava/lang/String;J)V
*/
JNIEXPORT void JNICALL Java_jnirtm_Transactionally_putLong__Ljava_lang_Object_2Ljava_lang_String_2J(JNIEnv* env, jclass _obsolete, jobject target, jstring fieldname, jlong value){
jclass targetClass = (*env)->GetObjectClass(env,target);

const char *str_fname = (*env)->GetStringUTFChars(env,fieldname,NULL);
jfieldID fidFLD = (*env)->GetFieldID(env, targetClass, str_fname, "J");

volatile int tries = 0;
volatile int success = 0;
while(!success){/*TODO: maybe switch to a different strategy when tries grows too large?*/
__asm__ __volatile__ (
"incl %0\n"
"xbegin 1f" /*1f: local label 1, look forward to find first*/
:"+rm"(tries)
:"rm"(success)/*artificial dependency to prevent re-ordering*/
);

/*do we need more artificial dependencies, here, to avoid re-ordering?*/

(*env)->SetLongField(env,targetClass,fidFLD,value);

__asm__ __volatile__ (
"xend\n\t"
"incl %0\n" /*increment success ==> break out of loop*/
"jmp 2f\n" /*jump to end of loop*/
"1:\n" /*local label 1 (jumped to when transaction is aborted)*/
"2:" /*local label 2 (jumped to after a successfully completed transaction)*/
:"+rm"(success)
:"rm"(tries) /*artificial dependency*/
);
}
#ifdef __TRX_DEBUG__
printf("putLong: (Ljava/lang/Object;Ljava/lang/String;J)V with %d tries\n",tries);
#endif
}

本质上是相同的(除了使用不同的方法来更改数据),但输出始终如一

putLong: (Ljava/lang/Object;Ljava/lang/String;J)V with 1 tries

每个方法每次运行都会被调用一次(来自 Java):

    //requires base class acquisition and field index lookup
Transactionally.putLong(base$x, "x",3L);
assert(data.x == 3);

//requires callback to java which then invokes intrinsics
Transactionally.putLong(Transactionally.unsafe, Transactionally.unsafe_class, base$x, off$x, 4L);
assert(data.x == 4);

程序运行时没有抛出断言错误,这只会让我更加困惑。

因为如果 assert(data.x == 4) 没有抛出错误,那么

(*env)-> CallVoidMethod(env,unsafe,midPutLong,base,off,value);

第一个C方法一定已经成功了。然而它成功了,但在启动事务之前没有执行 tries 的增量,也没有执行我在其周围插入的两个 printf

更新将 printf 添加到第二个方法中也不会打印它们。所以我猜想处于事务中会抑制 IO,并且仅 tries 计数器的行为有所不同。

为什么会发生这种情况以及如何阻止它?

更新

删除了 hello printfs,并且不确定如何直接创建 asm 代码,因此我反汇编了生成的 .so 文件。

放大重要的部分,

这是工作方法:

    while(!success){/*TODO: maybe switch to a different strategy when tries grows too large?*/
867: eb 41 jmp 8aa <Java_jnirtm_Transactionally_putLong__Ljava_lang_Object_2Ljava_lang_String_2J+0xda>
__asm__ __volatile__ (
869: 8b 45 e4 mov -0x1c(%rbp),%eax
86c: 8b 55 e0 mov -0x20(%rbp),%edx
86f: ff c2 inc %edx
871: c7 f8 30 00 00 00 xbeginq 8a7 <Java_jnirtm_Transactionally_putLong__Ljava_lang_Object_2Ljava_lang_String_2J+0xd7>
877: 89 55 e0 mov %edx,-0x20(%rbp)
:"rm"(success)/*artificial dependency to prevent re-ordering*/
);

/*do we need more artificial dependencies, here, to avoid re-ordering?*/

(*env)->SetLongField(env,targetClass,fidFLD,value);

[...]

8aa: 8b 45 e4 mov -0x1c(%rbp),%eax
8ad: 85 c0 test %eax,%eax
8af: 74 b8 je 869 <Java_jnirtm_Transactionally_putLong__Ljava_lang_Object_2Ljava_lang_String_2J+0x99>

这是来自错误的方法:

   while(!success){/*TODO: maybe switch to a different strategy when tries grows too large?*/
968: eb 5b jmp 9c5 <Java_jnirtm_Transactionally_putLong__Lsun_misc_Unsafe_2Ljava_lang_Class_2Ljava_lang_Object_2JJ+0xfb>
__asm__ __volatile__ (
96a: 8b 45 fc mov -0x4(%rbp),%eax
96d: 8b 55 f8 mov -0x8(%rbp),%edx
970: ff c2 inc %edx
972: c7 f8 4a 00 00 00 xbeginq 9c2 <Java_jnirtm_Transactionally_putLong__Lsun_misc_Unsafe_2Ljava_lang_Class_2Ljava_lang_Object_2JJ+0xf8>
978: 89 55 f8 mov %edx,-0x8(%rbp)
);

/*do we need more artificial dependencies, here, to avoid re-ordering?*/

//unsafe.putLong(base,off,value);
(*env)-> CallVoidMethod(env,unsafe,midPutLong,base,off,value);

[...]

9c5: 8b 45 fc mov -0x4(%rbp),%eax
9c8: 85 c0 test %eax,%eax
9ca: 74 9e je 96a <Java_jnirtm_Transactionally_putLong__Lsun_misc_Unsafe_2Ljava_lang_Class_2Ljava_lang_Object_2JJ+0xa0>

我仍然没有看到任何可以解释这种行为的相关差异。

完整对象转储

lib/libRTM_transact.so:     file format elf64-x86-64


Disassembly of section .init:

0000000000000670 <_init>:
670: 48 83 ec 08 sub $0x8,%rsp
674: 48 8b 05 5d 09 20 00 mov 0x20095d(%rip),%rax # 200fd8 <__gmon_start__>
67b: 48 85 c0 test %rax,%rax
67e: 74 02 je 682 <_init+0x12>
680: ff d0 callq *%rax
682: 48 83 c4 08 add $0x8,%rsp
686: c3 retq

Disassembly of section .plt:

0000000000000690 <.plt>:
690: ff 35 72 09 20 00 pushq 0x200972(%rip) # 201008 <_GLOBAL_OFFSET_TABLE_+0x8>
696: ff 25 74 09 20 00 jmpq *0x200974(%rip) # 201010 <_GLOBAL_OFFSET_TABLE_+0x10>
69c: 0f 1f 40 00 nopl 0x0(%rax)

00000000000006a0 <printf@plt>:
6a0: ff 25 72 09 20 00 jmpq *0x200972(%rip) # 201018 <printf@GLIBC_2.2.5>
6a6: 68 00 00 00 00 pushq $0x0
6ab: e9 e0 ff ff ff jmpq 690 <.plt>

00000000000006b0 <__assert_fail@plt>:
6b0: ff 25 6a 09 20 00 jmpq *0x20096a(%rip) # 201020 <__assert_fail@GLIBC_2.2.5>
6b6: 68 01 00 00 00 pushq $0x1
6bb: e9 d0 ff ff ff jmpq 690 <.plt>

Disassembly of section .plt.got:

00000000000006c0 <.plt.got>:
6c0: ff 25 32 09 20 00 jmpq *0x200932(%rip) # 200ff8 <__cxa_finalize@GLIBC_2.2.5>
6c6: 66 90 xchg %ax,%ax

Disassembly of section .text:

00000000000006d0 <deregister_tm_clones>:
6d0: 48 8d 3d 59 09 20 00 lea 0x200959(%rip),%rdi # 201030 <_edata>
6d7: 48 8d 05 59 09 20 00 lea 0x200959(%rip),%rax # 201037 <_edata+0x7>
6de: 55 push %rbp
6df: 48 29 f8 sub %rdi,%rax
6e2: 48 89 e5 mov %rsp,%rbp
6e5: 48 83 f8 0e cmp $0xe,%rax
6e9: 76 15 jbe 700 <deregister_tm_clones+0x30>
6eb: 48 8b 05 de 08 20 00 mov 0x2008de(%rip),%rax # 200fd0 <_ITM_deregisterTMCloneTable>
6f2: 48 85 c0 test %rax,%rax
6f5: 74 09 je 700 <deregister_tm_clones+0x30>
6f7: 5d pop %rbp
6f8: ff e0 jmpq *%rax
6fa: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
700: 5d pop %rbp
701: c3 retq
702: 0f 1f 40 00 nopl 0x0(%rax)
706: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
70d: 00 00 00

0000000000000710 <register_tm_clones>:
710: 48 8d 3d 19 09 20 00 lea 0x200919(%rip),%rdi # 201030 <_edata>
717: 48 8d 35 12 09 20 00 lea 0x200912(%rip),%rsi # 201030 <_edata>
71e: 55 push %rbp
71f: 48 29 fe sub %rdi,%rsi
722: 48 89 e5 mov %rsp,%rbp
725: 48 c1 fe 03 sar $0x3,%rsi
729: 48 89 f0 mov %rsi,%rax
72c: 48 c1 e8 3f shr $0x3f,%rax
730: 48 01 c6 add %rax,%rsi
733: 48 d1 fe sar %rsi
736: 74 18 je 750 <register_tm_clones+0x40>
738: 48 8b 05 b1 08 20 00 mov 0x2008b1(%rip),%rax # 200ff0 <_ITM_registerTMCloneTable>
73f: 48 85 c0 test %rax,%rax
742: 74 0c je 750 <register_tm_clones+0x40>
744: 5d pop %rbp
745: ff e0 jmpq *%rax
747: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
74e: 00 00
750: 5d pop %rbp
751: c3 retq
752: 0f 1f 40 00 nopl 0x0(%rax)
756: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
75d: 00 00 00

0000000000000760 <__do_global_dtors_aux>:
760: 80 3d c9 08 20 00 00 cmpb $0x0,0x2008c9(%rip) # 201030 <_edata>
767: 75 27 jne 790 <__do_global_dtors_aux+0x30>
769: 48 83 3d 87 08 20 00 cmpq $0x0,0x200887(%rip) # 200ff8 <__cxa_finalize@GLIBC_2.2.5>
770: 00
771: 55 push %rbp
772: 48 89 e5 mov %rsp,%rbp
775: 74 0c je 783 <__do_global_dtors_aux+0x23>
777: 48 8b 3d aa 08 20 00 mov 0x2008aa(%rip),%rdi # 201028 <__dso_handle>
77e: e8 3d ff ff ff callq 6c0 <.plt.got>
783: e8 48 ff ff ff callq 6d0 <deregister_tm_clones>
788: 5d pop %rbp
789: c6 05 a0 08 20 00 01 movb $0x1,0x2008a0(%rip) # 201030 <_edata>
790: f3 c3 repz retq
792: 0f 1f 40 00 nopl 0x0(%rax)
796: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
79d: 00 00 00

00000000000007a0 <frame_dummy>:
7a0: 48 8d 3d 61 06 20 00 lea 0x200661(%rip),%rdi # 200e08 <__JCR_END__>
7a7: 48 83 3f 00 cmpq $0x0,(%rdi)
7ab: 75 0b jne 7b8 <frame_dummy+0x18>
7ad: e9 5e ff ff ff jmpq 710 <register_tm_clones>
7b2: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
7b8: 48 8b 05 29 08 20 00 mov 0x200829(%rip),%rax # 200fe8 <_Jv_RegisterClasses>
7bf: 48 85 c0 test %rax,%rax
7c2: 74 e9 je 7ad <frame_dummy+0xd>
7c4: 55 push %rbp
7c5: 48 89 e5 mov %rsp,%rbp
7c8: ff d0 callq *%rax
7ca: 5d pop %rbp
7cb: e9 40 ff ff ff jmpq 710 <register_tm_clones>

00000000000007d0 <Java_jnirtm_Transactionally_putLong__Ljava_lang_Object_2Ljava_lang_String_2J>:
/*
* Class: jnirtm_Transactionally
* Method: putLong
* Signature: (Ljava/lang/Object;Ljava/lang/String;J)V
*/
JNIEXPORT void JNICALL Java_jnirtm_Transactionally_putLong__Ljava_lang_Object_2Ljava_lang_String_2J(JNIEnv* env, jclass _obsolete, jobject target, jstring fieldname, jlong value){
7d0: 55 push %rbp
7d1: 48 89 e5 mov %rsp,%rbp
7d4: 48 83 ec 50 sub $0x50,%rsp
7d8: 48 89 7d d8 mov %rdi,-0x28(%rbp)
7dc: 48 89 75 d0 mov %rsi,-0x30(%rbp)
7e0: 48 89 55 c8 mov %rdx,-0x38(%rbp)
7e4: 48 89 4d c0 mov %rcx,-0x40(%rbp)
7e8: 4c 89 45 b8 mov %r8,-0x48(%rbp)
jclass targetClass = (*env)->GetObjectClass(env,target);
7ec: 48 8b 45 d8 mov -0x28(%rbp),%rax
7f0: 48 8b 00 mov (%rax),%rax
7f3: 48 8b 80 f8 00 00 00 mov 0xf8(%rax),%rax
7fa: 48 8b 4d c8 mov -0x38(%rbp),%rcx
7fe: 48 8b 55 d8 mov -0x28(%rbp),%rdx
802: 48 89 ce mov %rcx,%rsi
805: 48 89 d7 mov %rdx,%rdi
808: ff d0 callq *%rax
80a: 48 89 45 e8 mov %rax,-0x18(%rbp)

const char *str_fname = (*env)->GetStringUTFChars(env,fieldname,NULL);
80e: 48 8b 45 d8 mov -0x28(%rbp),%rax
812: 48 8b 00 mov (%rax),%rax
815: 48 8b 80 48 05 00 00 mov 0x548(%rax),%rax
81c: 48 8b 75 c0 mov -0x40(%rbp),%rsi
820: 48 8b 4d d8 mov -0x28(%rbp),%rcx
824: ba 00 00 00 00 mov $0x0,%edx
829: 48 89 cf mov %rcx,%rdi
82c: ff d0 callq *%rax
82e: 48 89 45 f0 mov %rax,-0x10(%rbp)
jfieldID fidFLD = (*env)->GetFieldID(env, targetClass, str_fname, "J");
832: 48 8b 45 d8 mov -0x28(%rbp),%rax
836: 48 8b 00 mov (%rax),%rax
839: 48 8b 80 f0 02 00 00 mov 0x2f0(%rax),%rax
840: 48 8b 55 f0 mov -0x10(%rbp),%rdx
844: 48 8b 75 e8 mov -0x18(%rbp),%rsi
848: 48 8b 7d d8 mov -0x28(%rbp),%rdi
84c: 48 8d 0d ad 01 00 00 lea 0x1ad(%rip),%rcx # a00 <_fini+0x18>
853: ff d0 callq *%rax
855: 48 89 45 f8 mov %rax,-0x8(%rbp)

volatile int tries = 0;
859: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%rbp)
volatile int success = 0;
860: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%rbp)
while(!success){/*TODO: maybe switch to a different strategy when tries grows too large?*/
867: eb 41 jmp 8aa <Java_jnirtm_Transactionally_putLong__Ljava_lang_Object_2Ljava_lang_String_2J+0xda>
__asm__ __volatile__ (
869: 8b 45 e4 mov -0x1c(%rbp),%eax
86c: 8b 55 e0 mov -0x20(%rbp),%edx
86f: ff c2 inc %edx
871: c7 f8 30 00 00 00 xbeginq 8a7 <Java_jnirtm_Transactionally_putLong__Ljava_lang_Object_2Ljava_lang_String_2J+0xd7>
877: 89 55 e0 mov %edx,-0x20(%rbp)
:"rm"(success)/*artificial dependency to prevent re-ordering*/
);

/*do we need more artificial dependencies, here, to avoid re-ordering?*/

(*env)->SetLongField(env,targetClass,fidFLD,value);
87a: 48 8b 45 d8 mov -0x28(%rbp),%rax
87e: 48 8b 00 mov (%rax),%rax
881: 48 8b 80 70 03 00 00 mov 0x370(%rax),%rax
888: 48 8b 4d b8 mov -0x48(%rbp),%rcx
88c: 48 8b 55 f8 mov -0x8(%rbp),%rdx
890: 48 8b 75 e8 mov -0x18(%rbp),%rsi
894: 48 8b 7d d8 mov -0x28(%rbp),%rdi
898: ff d0 callq *%rax

__asm__ __volatile__ (
89a: 8b 45 e0 mov -0x20(%rbp),%eax
89d: 8b 55 e4 mov -0x1c(%rbp),%edx
8a0: 0f 01 d5 xend
8a3: ff c2 inc %edx
8a5: eb 00 jmp 8a7 <Java_jnirtm_Transactionally_putLong__Ljava_lang_Object_2Ljava_lang_String_2J+0xd7>
8a7: 89 55 e4 mov %edx,-0x1c(%rbp)
while(!success){/*TODO: maybe switch to a different strategy when tries grows too large?*/
8aa: 8b 45 e4 mov -0x1c(%rbp),%eax
8ad: 85 c0 test %eax,%eax
8af: 74 b8 je 869 <Java_jnirtm_Transactionally_putLong__Ljava_lang_Object_2Ljava_lang_String_2J+0x99>
:"+rm"(success)
:"rm"(tries) /*artificial dependency*/
);
}
#ifdef __TRX_DEBUG__
printf("putLong: (Ljava/lang/Object;Ljava/lang/String;J)V with %d tries\n",tries);
8b1: 8b 45 e0 mov -0x20(%rbp),%eax
8b4: 89 c6 mov %eax,%esi
8b6: 48 8d 3d 4b 01 00 00 lea 0x14b(%rip),%rdi # a08 <_fini+0x20>
8bd: b8 00 00 00 00 mov $0x0,%eax
8c2: e8 d9 fd ff ff callq 6a0 <printf@plt>
#endif
}
8c7: 90 nop
8c8: c9 leaveq
8c9: c3 retq

00000000000008ca <Java_jnirtm_Transactionally_putLong__Lsun_misc_Unsafe_2Ljava_lang_Class_2Ljava_lang_Object_2JJ>:
jobject unsafe,
jclass unsafe_class,
jobject base,
jlong off,
jlong value
){
8ca: 55 push %rbp
8cb: 48 89 e5 mov %rsp,%rbp
8ce: 48 83 ec 40 sub $0x40,%rsp
8d2: 48 89 7d e8 mov %rdi,-0x18(%rbp)
8d6: 48 89 75 e0 mov %rsi,-0x20(%rbp)
8da: 48 89 55 d8 mov %rdx,-0x28(%rbp)
8de: 48 89 4d d0 mov %rcx,-0x30(%rbp)
8e2: 4c 89 45 c8 mov %r8,-0x38(%rbp)
8e6: 4c 89 4d c0 mov %r9,-0x40(%rbp)
if(midPutLong == NULL){
8ea: 48 8b 05 ef 06 20 00 mov 0x2006ef(%rip),%rax # 200fe0 <midPutLong@@Base-0x58>
8f1: 48 8b 00 mov (%rax),%rax
8f4: 48 85 c0 test %rax,%rax
8f7: 75 61 jne 95a <Java_jnirtm_Transactionally_putLong__Lsun_misc_Unsafe_2Ljava_lang_Class_2Ljava_lang_Object_2JJ+0x90>
midPutLong = (*env)->GetMethodID(env,unsafe_class,"putLong","(Ljava/lang/Object;JJ)V");
8f9: 48 8b 45 e8 mov -0x18(%rbp),%rax
8fd: 48 8b 00 mov (%rax),%rax
900: 48 8b 80 08 01 00 00 mov 0x108(%rax),%rax
907: 48 8b 75 d0 mov -0x30(%rbp),%rsi
90b: 48 8b 7d e8 mov -0x18(%rbp),%rdi
90f: 48 8d 0d 33 01 00 00 lea 0x133(%rip),%rcx # a49 <_fini+0x61>
916: 48 8d 15 44 01 00 00 lea 0x144(%rip),%rdx # a61 <_fini+0x79>
91d: ff d0 callq *%rax
91f: 48 89 c2 mov %rax,%rdx
922: 48 8b 05 b7 06 20 00 mov 0x2006b7(%rip),%rax # 200fe0 <midPutLong@@Base-0x58>
929: 48 89 10 mov %rdx,(%rax)
#ifdef __TRX_ASSERT__
assert(midPutLong != NULL);
92c: 48 8b 05 ad 06 20 00 mov 0x2006ad(%rip),%rax # 200fe0 <midPutLong@@Base-0x58>
933: 48 8b 00 mov (%rax),%rax
936: 48 85 c0 test %rax,%rax
939: 75 1f jne 95a <Java_jnirtm_Transactionally_putLong__Lsun_misc_Unsafe_2Ljava_lang_Class_2Ljava_lang_Object_2JJ+0x90>
93b: 48 8d 0d be 01 00 00 lea 0x1be(%rip),%rcx # b00 <__PRETTY_FUNCTION__.3410>
942: ba 43 00 00 00 mov $0x43,%edx
947: 48 8d 35 1b 01 00 00 lea 0x11b(%rip),%rsi # a69 <_fini+0x81>
94e: 48 8d 3d 2d 01 00 00 lea 0x12d(%rip),%rdi # a82 <_fini+0x9a>
955: e8 56 fd ff ff callq 6b0 <__assert_fail@plt>
#endif
}

volatile int tries = 0;
95a: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp)
volatile int success = 0;
961: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
while(!success){/*TODO: maybe switch to a different strategy when tries grows too large?*/
968: eb 5b jmp 9c5 <Java_jnirtm_Transactionally_putLong__Lsun_misc_Unsafe_2Ljava_lang_Class_2Ljava_lang_Object_2JJ+0xfb>
__asm__ __volatile__ (
96a: 8b 45 fc mov -0x4(%rbp),%eax
96d: 8b 55 f8 mov -0x8(%rbp),%edx
970: ff c2 inc %edx
972: c7 f8 4a 00 00 00 xbeginq 9c2 <Java_jnirtm_Transactionally_putLong__Lsun_misc_Unsafe_2Ljava_lang_Class_2Ljava_lang_Object_2JJ+0xf8>
978: 89 55 f8 mov %edx,-0x8(%rbp)
);

/*do we need more artificial dependencies, here, to avoid re-ordering?*/

//unsafe.putInt(base,off,value);
(*env)-> CallVoidMethod(env,unsafe,midPutLong,base,off,value);
97b: 48 8b 45 e8 mov -0x18(%rbp),%rax
97f: 48 8b 00 mov (%rax),%rax
982: 4c 8b 90 e8 01 00 00 mov 0x1e8(%rax),%r10
989: 48 8b 05 50 06 20 00 mov 0x200650(%rip),%rax # 200fe0 <midPutLong@@Base-0x58>
990: 48 8b 10 mov (%rax),%rdx
993: 48 8b 7d c0 mov -0x40(%rbp),%rdi
997: 48 8b 4d c8 mov -0x38(%rbp),%rcx
99b: 48 8b 75 d8 mov -0x28(%rbp),%rsi
99f: 48 8b 45 e8 mov -0x18(%rbp),%rax
9a3: 4c 8b 4d 10 mov 0x10(%rbp),%r9
9a7: 49 89 f8 mov %rdi,%r8
9aa: 48 89 c7 mov %rax,%rdi
9ad: b8 00 00 00 00 mov $0x0,%eax
9b2: 41 ff d2 callq *%r10

__asm__ __volatile__ (
9b5: 8b 45 f8 mov -0x8(%rbp),%eax
9b8: 8b 55 fc mov -0x4(%rbp),%edx
9bb: 0f 01 d5 xend
9be: ff c2 inc %edx
9c0: eb 00 jmp 9c2 <Java_jnirtm_Transactionally_putLong__Lsun_misc_Unsafe_2Ljava_lang_Class_2Ljava_lang_Object_2JJ+0xf8>
9c2: 89 55 fc mov %edx,-0x4(%rbp)
while(!success){/*TODO: maybe switch to a different strategy when tries grows too large?*/
9c5: 8b 45 fc mov -0x4(%rbp),%eax
9c8: 85 c0 test %eax,%eax
9ca: 74 9e je 96a <Java_jnirtm_Transactionally_putLong__Lsun_misc_Unsafe_2Ljava_lang_Class_2Ljava_lang_Object_2JJ+0xa0>
:"+rm"(success)
:"rm"(tries) /*artificial dependency*/
);
}
#ifdef __TRX_DEBUG__
printf("putLong: (Lsun/misc/Unsafe;Ljava/lang/Class;Ljava/lang/Object;JJ)V with %d tries\n",tries);
9cc: 8b 45 f8 mov -0x8(%rbp),%eax
9cf: 89 c6 mov %eax,%esi
9d1: 48 8d 3d c0 00 00 00 lea 0xc0(%rip),%rdi # a98 <_fini+0xb0>
9d8: b8 00 00 00 00 mov $0x0,%eax
9dd: e8 be fc ff ff callq 6a0 <printf@plt>
#endif
}
9e2: 90 nop
9e3: c9 leaveq
9e4: c3 retq

Disassembly of section .fini:

00000000000009e8 <_fini>:
9e8: 48 83 ec 08 sub $0x8,%rsp
9ec: 48 83 c4 08 add $0x8,%rsp
9f0: c3 retq

最佳答案

事务中无法执行 I/O,因此 printf 调用可能会中止事务。然后控制传递到 1: 标签,这是未定义的行为,因为不允许在 asm 语句之间跳转,并且 eax 被修改而不列出在破坏列表或输出列表中。

xbegin 的目标需要位于同一个 asm 语句中,或者是使用 asm 引用的 C 标签 goto 扩展名。或者更好地使用内在函数并避免内联汇编。

关于java - 程序丢失一个增量和两个 `` printf``s,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47284960/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com