I wrote this simple Java program:
package com.salil.threads; public class IncrementClass { static volatile int j = 0; static int i = 0; public static void main(String args[]) { for(int a=0;a<1000000;a++); i++; j++; } }
This generates the following disassembled code for i ++ and j ++ (the remaining disassembled code is removed):
0x0000000002961a6c: 49ba98e8d0d507000000 mov r10,7d5d0e898h ; {oop(a 'java/lang/Class' = 'com/salil/threads/IncrementClass')} 0x0000000002961a76: 41ff4274 inc dword ptr [r10+74h] ;*if_icmpge ; - com.salil.threads.IncrementClass::main@5 (line 10) 0x0000000002961a7a: 458b5a70 mov r11d,dword ptr [r10+70h] 0x0000000002961a7e: 41ffc3 inc r11d 0x0000000002961a81: 45895a70 mov dword ptr [r10+70h],r11d 0x0000000002961a85: f083042400 lock add dword ptr [rsp],0h ;*putstatic j ; - com.salil.threads.IncrementClass::main@27 (line 14)
Here is what I understand about the following assembler:
- mov r10,7d5d0e898h: moves the pointer to IncrementClass.class to register r10
- inc dword ptr [r10 + 74h]: increments the value of 4 bytes at the address by [r10 + 74h], (ie)
- mov r11d, dword ptr [r10 + 70h]: moves the value of value 4 to the address [r10 + 70h] for registering r11d (for example, the value of moving j in r11d)
- inc r11d: Increment r11d
- mov dword ptr [r10 + 70h], r11d: write the value r11d to [r10 + 70h] so that it is visible to other threads -lock add dword ptr [rsp], 0h: block the memory address represented by the pointer to the rsp stack and add to him 0.
JMM states that there should be a load memory barrier before every volatile read, and there should be a storage barrier after every volatile write. My question is:
- Why is there no load barrier before reading j in r11d?
- How locking and adding to rsp ensures that the j value in r11d is passed back to main memory. All I read from the intel specs is that locking provides the processor with exclusive locking at the specified memory address for the duration of the action.
java assembly multithreading intel
Salil surendran
source share