RFR: 8139457: Array bases are aligned at HeapWord granularity [v51]

Roman Kennke rkennke at openjdk.org
Fri Aug 18 16:23:47 UTC 2023


On Fri, 18 Aug 2023 07:44:41 GMT, Stefan Karlsson <stefank at openjdk.org> wrote:

> There is something odd going on with the `arrayOopDesc::header_size()` implementation. In some configurations the array length is within the header size, but that's not always the case.
> 
> This picture shows "header_size_in_bytes()" for different 64-bits configurations:
> 
> ```
>  ====================================== Array ========================================
>  ===================== Full Klass ====================         === Compressed Klass ==
>   Aligned Field                   Unaligned Field                Auto Aligned Field     
> +-----------------------+     +-----------------------+       +-----------------------+ 
> | Mark 0                |     | Mark 0                |       | Mark 0                | 
> +-----------------------+     +-----------------------+       +-----------------------+ 
> | Mark 1                |     | Mark 1                |       | Mark 1                | 
> +-----------------------+     +-----------------------+       +-----------------------+ 
> | Klass 0               |     | Klass 0               |       | Compressed Klass      | 
> +-----------------------+     +-----------------------+       +-----------------------+ 
> | Klass 1               |     | Klass 1               |       | Length                | 
> +-----------------------+     +-----------------------+    +- +-----------------------+ 
> | Length                |     | Length                |    |  | Field 0               |  
> +-----------------------+ -+  +-----------------------+ -+ |  +-----------------------+  
> | Gap                   |  |  | Field 0               |  | |  | Field 1               |  
> +-----------------------+  |  +-----------------------+  | |  +-----------------------+  
> | Field 0               |  |  | Field 1               |  | |  
> +-----------------------+  |  +-----------------------+  | |  
> | Field 1               |  |  | Padding               |  | |  
> +-----------------------+  |  +-----------------------+  | |   
>                            |                             | |  
>                            +-----------------------------+-+
>                            |
> 			   +------- new arrayOopDesc::header_size_in_bytes()
> ```
> 
> This looks reasonable. If I draw the same picture for `header_size()` I get this:
> 
> ```
>  ====================================== Array ========================================
>  ===================== Full Klass ====================         === Compressed Klass ==
>   Aligned Field                  Unaligned Field                 Auto Aligned Field     
> +-----------------------+     +-----------------------+       +-----------------------+ 
> | Mark 0                |     | Mark 0                |       | Mark 0                | 
> +-----------------------+     +-----------------------+       +-----------------------+ 
> | Mark 1                |     | Mark 1                |       | Mark 1                | 
> +-----------------------+     +-----------------------+       +-----------------------+ 
> | Klass 0               |     | Klass 0               |       | Compressed Klass      | 
> +-----------------------+     +-----------------------+       +-----------------------+ 
> | Klass 1               |     | Klass 1               |       | Length                | 
> +-----------------------+ -+  +-----------------------+    +- +-----------------------+ 
> | Length                |  |  | Length                |    |  | Field 0               |  
> +-----------------------+  |  +-----------------------+    |  +-----------------------+  
> | Gap                   |  |  | Field 0               |    |  | Field 1               |  
> +-----------------------+  |  +-----------------------+ -+ |  +-----------------------+  
> | Field 0               |  |  | Field 1               |  | |  
> +-----------------------+  |  +-----------------------+  | |  
> | Field 1               |  |  | Padding               |  | |  
> +-----------------------+  |  +-----------------------+  | |   
>                            |                             | |  
>                            +-----------------------------+-+
> 			   |
> 			   +------- new arrayOopDesc::header_size()
> ```
> 
> I've verified that this is the case by running the following gtest:
> 
> ```
> TEST_VM(arrayOopDesc, header_size_in_bytes) {
> #ifdef _LP64
>   {
>     FlagSetting fs(UseCompressedClassPointers, false);
>     // Array length starts at 16
>     EXPECT_EQ(arrayOopDesc::length_offset_in_bytes(), 16);
> 
>     // Header size in bytes includes the length.
>     EXPECT_EQ(arrayOopDesc::header_size_in_bytes(), 20);
> 
>     // arrayOopDesc::header_size implies that one of the elements are included in the header
>     EXPECT_EQ(arrayOopDesc::header_size(T_BOOLEAN) * HeapWordSize, 24);
> 
>     // Without compressed oops not even the length is included in the header
>     FlagSetting fs2(UseCompressedOops, false);
>     EXPECT_EQ(arrayOopDesc::header_size(T_OBJECT) * HeapWordSize,  16);
> 
>     // With compressed oops the length and and one of the oops are included in the header
>     FlagSetting fs3(UseCompressedOops, true);
>     EXPECT_EQ(arrayOopDesc::header_size(T_OBJECT) * HeapWordSize,  24);
>   }
> #endif
> }
> ```
> 
> (Note: I had to turn off the assert in `header_size_in_bytes()` to get the test to work)
> 
> The problem is that `header_size_in_bytes` used to return a HeapWordSize-aligned value, which allowed for a non-lossy division in the line `align_object_offset(typesize_in_bytes/HeapWordSize)`.
> 
> I think this should be fixed and I think it would make sense to add complete tests for arrayOopDesc::heap_size(), similar to what you did for base_offset_in_bytes.

Thanks, Stefan for checking this. Yes, arrayOop::header_size() is confusing. The only purpose of this method is to help a few code paths which need the header_size_in_bytes() to be aligned-up and converted to word-size. Not quite sure how to deal with it. Move it out to some different place? Name it differently?

-------------

PR Comment: https://git.openjdk.org/jdk/pull/11044#issuecomment-1684147706


More information about the hotspot-dev mailing list