小编use*_*818的帖子

Hotspot JIT编译器是否可以重现任何指令重新排序?

我们知道,一些JIT允许重新排序对象初始化,例如,

someRef = new SomeObject();
Run Code Online (Sandbox Code Playgroud)

可以分解为以下步骤:

objRef = allocate space for SomeObject; //step1
call constructor of SomeObject;         //step2
someRef = objRef;                    //step3
Run Code Online (Sandbox Code Playgroud)

JIT编译器可能会重新排序如下:

objRef = allocate space for SomeObject; //step1
someRef = objRef;                    //step3
call constructor of SomeObject;         //step2
Run Code Online (Sandbox Code Playgroud)

即,步骤2和步骤3可以由JIT编译器重新排序.虽然这在理论上是有效的重新排序,但我无法使用x86平台下的Hotspot(jdk1.7)重现它.

那么,Hotspot JIT comipler是否可以重现任何指令重新排序?


更新:我使用以下命令在我的机器(Linux x86_64,JDK 1.8.0_40,i5-3210M)上进行了测试:

java -XX:-UseCompressedOops -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand="print org.openjdk.jcstress.tests.unsafe.UnsafePublication::publish" -XX:CompileCommand="inline, org.openjdk.jcstress.tests.unsafe.UnsafePublication::publish" -XX:PrintAssemblyOptions=intel -jar tests-custom/target/jcstress.jar -f -1 -t .*UnsafePublication.* -v > log.txt 
Run Code Online (Sandbox Code Playgroud)

我可以看到该工具报告的内容如下:

[1] 5可接受对象已发布,至少有1个字段可见.

这意味着观察者线程看到了一个未初始化的MyObject实例.

但是,我没有看到像@ Ivan那样生成的汇编代码:

0x00007f71d4a15e34: mov r11d,DWORD PTR …
Run Code Online (Sandbox Code Playgroud)

java multithreading jit jvm jvm-hotspot

16
推荐指数
1
解决办法
581
查看次数

"内化"在JVM源代码中意味着什么?

'intrinsify'是否意味着JVM的源代码有些"保守",但JVM编译器可以在JVM预热时进行一些优化?例如,

UNSAFE_ENTRY(void, Unsafe_SetOrderedObject(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
  UnsafeWrapper("Unsafe_SetOrderedObject");
  oop x = JNIHandles::resolve(x_h);
  oop p = JNIHandles::resolve(obj);
  void* addr = index_oop_from_field_offset_long(p, offset);
  OrderAccess::release();
  if (UseCompressedOops) {
    oop_store((narrowOop*)addr, x);
  } else {
    oop_store((oop*)addr, x);
  }
  OrderAccess::fence();  <==There is a full memory barrier to ensure visibility which is NOT strictly required
UNSAFE_END
Run Code Online (Sandbox Code Playgroud)

putOrderedObject不需要确保immediate visiblity,但我们可以看到存储器附加了一个完整的内存屏障到指定的对象,所以我说JVM是conservative,但是JIT编译器可以在运行时优化这个内存屏障,这就是所谓的instrinsify,我是对的?

java multithreading jvm

7
推荐指数
1
解决办法
702
查看次数

什么是Java同步的有效重新排序?

许多人问这样的类似问题,但他们的答案都没有让我满意.我非常确定的唯一两个重新排序规则如下:

  1. 只要它确认为as-if-serial语义,就允许对synchronized块内的操作(​​或者只是调用它的关键部分)进行重新排序.
  2. 不允许将操作(包括读取和写入)移动(重新排序)到关键部分之外.

但是,对于同步块之前或之后的那些操作,它们是否可以移动到临界区?对于这个问题,我发现有些相反.例如,cookbook说编译器会在MonitorEnter之后和MonitorExit之前插入一些障碍:

MonitorEnter
 (any other needed instructions go here )
[LoadLoad] <===MB1:Inserted memory barrier
[LoadStore] <===MB2:Inserted memory barrier
(Begin of critical section)

....
(end of critical section)
[LoadStore] <===MB3:Inserted memory barrier
[StoreStore] <===MB4:Inserted memory barrier
 (any other needed instructions go here )
MonitorExit
Run Code Online (Sandbox Code Playgroud)

根据以上编译器的位置并给出下面的伪代码:

  Load a;
  Load b;
  Store 1;
  Store 2;
  MonitorEnter
     (any other needed instructions go here )
    [LoadLoad] <===MB1
    [LoadStore] <===MB2
    (Begin of critical section)

    ....
    (end of …
Run Code Online (Sandbox Code Playgroud)

java multithreading

5
推荐指数
1
解决办法
268
查看次数

ARM 处理器是否有无效队列?

ARM 处理器是否有无效队列?我查找了 ARM 架构参考手册[ https://www.scss.tcd.ie/~waldroj/3d1/arm_arm.pdf],但它没有提到“无效队列”(它确实提到了“写入缓冲区”),那么这是否意味着ARM没有无效队列?

multithreading arm processor cpu-architecture

5
推荐指数
0
解决办法
102
查看次数