-
Bug
-
Resolution: Fixed
-
P2
-
10
The TestOptionsWithRanges.java fails as when the test launches the following commandline, there is a SIGSEGV:
java -server -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=TestOptionsWithRanges.jsa -Xshare:dump -XX:SharedBaseAddress=2147483648
See the attached TestOptionsWithRanges.jtr for the full results.
The crash occurs in the code generated by:
void TemplateTable::_return(TosState state)
for " _return_register_finalizer" - this is why the initializer of Object is failing.
The failing code is generated by
TemplateTable::_return
MacroAssembler::load_klass
MacroAssembler::decode_klass_not_null
We execute in decode_klass_not_null the clause triggered by MacroAssembler::use_XOR_for_compressed_class_base .
If that is set, we generated a shift (optional) and then a eor to generate the address.
The MacroAssembler initializer sets the flag with the following logic:
use_XOR_for_compressed_class_base
= (operand_valid_for_logical_immediate(false /*is32*/,
(uint64_t)Universe::narrow_klass_base())
&& ((uint64_t)Universe::narrow_klass_base()
> (1u << log2_intptr(CompressedClassSpaceSize))));
So if the narrow_klass_base is larger than the highest bit of the CompressedClassSpaceSize then logically we eor the base address onto the address.
Like so:
0x000003ff98959da8: ldr x1, [x24]
0x000003ff98959dac: ldr w3, [x1, #8]
0x000003ff98959db0: lsl x3, x3, #3
0x000003ff98959db4: eor x3, x3, #0x80000000
We get the situation where a bad address is generated when the class is accessed.
Given x3 starting as 0x18002a86, we should get the following:
(0x18002a86L <<3)+0x80000000L = 0x140015430
Instead the calculation is :
(0x18002a86L <<3l) ^ 0x80000000L = 0x40015430
Which is incorrect, and causes a crash.
The problem is because the CompressedClassSpaceSize doesn't encompass the full range of memory allocated for classes.
The method MetaspaceShared::initialize_dumptime_shared_and_meta_space does the initialization, and allocates 4GB on LP64 systems. The "CompressedClassSpaceSize" is set here.
The dumping process reports the following:
narrow_klass_base = 0x00000000 8000 0000, narrow_klass_shift = 3
Allocated temporary class space: 1073741824 bytes at 0x0000000 1 4000 0000 <- 0x80000000 + 3GB
Allocated shared space: 3221225472 bytes at 0x00000000 8000 0000 < +3GB
The address of the class is within the temporary class space. Plainly if the classes are being allocated within a memory space of 4GB, we're not going to be able to generate addresses by XORing a base value that is at or below the most significant bits of the unshifted address.
I have modified the constructor of MacroAssembler to set use_XOR_for_compressed_class_base using 4GB as the size of the compressed class area, ignoring the parameter. Superficially this tests ok. Using eor will be valid with base addresses over 4GB.
I don't think the CompressedClassSpaceSize parameter is being respected - I'll do more testing.
java -server -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:SharedArchiveFile=TestOptionsWithRanges.jsa -Xshare:dump -XX:SharedBaseAddress=2147483648
See the attached TestOptionsWithRanges.jtr for the full results.
The crash occurs in the code generated by:
void TemplateTable::_return(TosState state)
for " _return_register_finalizer" - this is why the initializer of Object is failing.
The failing code is generated by
TemplateTable::_return
MacroAssembler::load_klass
MacroAssembler::decode_klass_not_null
We execute in decode_klass_not_null the clause triggered by MacroAssembler::use_XOR_for_compressed_class_base .
If that is set, we generated a shift (optional) and then a eor to generate the address.
The MacroAssembler initializer sets the flag with the following logic:
use_XOR_for_compressed_class_base
= (operand_valid_for_logical_immediate(false /*is32*/,
(uint64_t)Universe::narrow_klass_base())
&& ((uint64_t)Universe::narrow_klass_base()
> (1u << log2_intptr(CompressedClassSpaceSize))));
So if the narrow_klass_base is larger than the highest bit of the CompressedClassSpaceSize then logically we eor the base address onto the address.
Like so:
0x000003ff98959da8: ldr x1, [x24]
0x000003ff98959dac: ldr w3, [x1, #8]
0x000003ff98959db0: lsl x3, x3, #3
0x000003ff98959db4: eor x3, x3, #0x80000000
We get the situation where a bad address is generated when the class is accessed.
Given x3 starting as 0x18002a86, we should get the following:
(0x18002a86L <<3)+0x80000000L = 0x140015430
Instead the calculation is :
(0x18002a86L <<3l) ^ 0x80000000L = 0x40015430
Which is incorrect, and causes a crash.
The problem is because the CompressedClassSpaceSize doesn't encompass the full range of memory allocated for classes.
The method MetaspaceShared::initialize_dumptime_shared_and_meta_space does the initialization, and allocates 4GB on LP64 systems. The "CompressedClassSpaceSize" is set here.
The dumping process reports the following:
narrow_klass_base = 0x00000000 8000 0000, narrow_klass_shift = 3
Allocated temporary class space: 1073741824 bytes at 0x0000000 1 4000 0000 <- 0x80000000 + 3GB
Allocated shared space: 3221225472 bytes at 0x00000000 8000 0000 < +3GB
The address of the class is within the temporary class space. Plainly if the classes are being allocated within a memory space of 4GB, we're not going to be able to generate addresses by XORing a base value that is at or below the most significant bits of the unshifted address.
I have modified the constructor of MacroAssembler to set use_XOR_for_compressed_class_base using 4GB as the size of the compressed class area, ignoring the parameter. Superficially this tests ok. Using eor will be valid with base addresses over 4GB.
I don't think the CompressedClassSpaceSize parameter is being respected - I'll do more testing.