- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在下面的方法中,我们设置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/
我想知道以下语句在 C 中会打印什么? printf("hello\n") || (printf("goodbye\n") || printf("world\n")); 我通常习惯于使用“cout”在
这是我目前正在学习的系统编程类(class)的幻灯片: catch_child 是 SIGCHLD 处理程序。输出与代码如何对应?为什么没有打印一些“Child #x started”消息? 最佳答案
这有点像拼图……我刚刚又回到了C,打算这次掌握它。所以我一直在阅读 The C Programming Language ,我得到了这个声明: Among others, printf also re
如何使用 printf 在字符串末尾附加空格? 我找不到任何在右侧附加空格的示例。 A similar question我发现使用 printf改为在字符串的左侧添加空格。 最佳答案 使用负数左对齐(
我想通过 usart 从 stm32f405 注销。 在我的 syscall.c 文件中,我实现了通过 usart 打印的功能: int _write(int file, char *ptr, int
我想定义一个记录器函数,比如 myPutStrLn = putStrLn . (++) "log: " main = do myPutStrLn "hello" 这很好。现在我想用 printf 格式
Printf module API详细介绍了类型转换标志,其中: %B: convert a boolean argument to the string true or false %b: conv
@H2CO3 这是我的主要代码: #pragma OPENCL EXTENSION cl_ amd_ printf : enable #define PROGRAM_FILE "matvec.cl"
Printf module API详细介绍了类型转换标志,其中: %B: convert a boolean argument to the string true or false %b: conv
您可以使用 printf 字段宽度说明符截断字符串: printf("%.5s", "abcdefgh"); > abcde 不幸的是,它不适用于数字(将 d 替换为 x 是相同的): printf(
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 4 年前。 Improve th
我遇到了我见过的最奇怪的错误之一。 我有一个简单的程序,可以打印多个整数数组。 对数组进行排序,然后打印...... place_in_buf(n100, 100); insertion(10
我的程序是每隔一段时间获取文件大小并显示它以记录任何更改。由于某种原因,执行下面的代码挂起,只为我提供了一个光标。没有打印或显示任何内容。 代码: #include #include #inclu
printf("It is currently %s's turn.\n", current->name); 我想知道为什么在 %s 之后打印出额外的换行符。我知道C 中的字符串总是以\0 结尾。没有
这个问题已经有答案了: printf anomaly after "fork()" (3 个回答) fork() in c using printf [duplicate] (2 个回答) 已关闭 9
我对编程很陌生。 我正在尝试编写一个程序,从数组中调用水果的价格。但我希望代码在写价格之前也写水果的名称。如果我键入 2,如何使输出为“Orange price : 10”而不仅仅是 price :
这个问题在这里已经有了答案: How do I print a non-null-terminated string using printf? (2 个答案) 关闭 7 年前。 例如,我有一个字符
我有一个 atmel UC3-L0 和罗盘传感器。现在我安装 AtmelStudio 并将一些演示代码下载到电路板中。但是我不知道演示代码中的函数 printf 会在哪里出现数据。我应该如何获取数据?
我有一个 atmel UC3-L0 和罗盘传感器。现在我安装 AtmelStudio 并将一些演示代码下载到电路板中。但是我不知道演示代码中的函数 printf 会在哪里出现数据。我应该如何获取数据?
嗨,我是 C 世界的新手,我的代码确实有些奇怪。目标是创建一个函数,可以在开头和结尾处用空格和/或制表符修剪字符串。我无法使用字符串库。 问题是我的代码中有一个 printf 只是用于测试,它的工作非
我是一名优秀的程序员,十分优秀!