Since JDK-8338526, we keep only those Klass in class space that need to be encodable with a narrowKlass.
To check whether a Klass can be encoded, we call `CompressedKlassPointers::is_in_encodable_range()`. Unfortunately there is an error that results from the confusion around "encoding range" vs "klass range" when it comes to narrowKlass encoding. These terms are not cleanly used and therefore errors like this happen.
The "Encoding Range" is the range that can be encoded with the current encoding base, encoding shift and (implicitly) the bit size of the narrowKlass. The encoding range reaches from `[ <encoding base> ... <encoding base> + 1 << (32 + <encoding shift>) ).`. Its size is either 4G (shift=0) or 32G (shift=3).
The "Klass Range" is the range within the encoding range that actually holds Klass structures. It is usually just a small part of the encoding range:
- With zero-based encoding, the encoding base is zero, so it precedes the start of the Klass range
- and usually the encoding range reaches far beyond the Klass range, since the class space is just 1GB.
----
The error in this case, introduced with 8338526, was that we use the range `[<encoding base> ... <klass range end>)` for `is_in_encodable_range()`. That can lead to false positives. Since the base can be zero, a non-class Metaspage region may live in address regions below the Klass range (between `0` and `<klass range start>`). A Klass in that region would falsely be recognized as "is encodable" even though it lives not in the klass range.
The error is extremely unlikely to happen, mostly because non-class Metaspace regions - freely placed by the OS - typically live in high-address ranges far beyond a low-placed class space, and also it is restricted to zero-based encoding which is only used if CDS is disabled.
To check whether a Klass can be encoded, we call `CompressedKlassPointers::is_in_encodable_range()`. Unfortunately there is an error that results from the confusion around "encoding range" vs "klass range" when it comes to narrowKlass encoding. These terms are not cleanly used and therefore errors like this happen.
The "Encoding Range" is the range that can be encoded with the current encoding base, encoding shift and (implicitly) the bit size of the narrowKlass. The encoding range reaches from `[ <encoding base> ... <encoding base> + 1 << (32 + <encoding shift>) ).`. Its size is either 4G (shift=0) or 32G (shift=3).
The "Klass Range" is the range within the encoding range that actually holds Klass structures. It is usually just a small part of the encoding range:
- With zero-based encoding, the encoding base is zero, so it precedes the start of the Klass range
- and usually the encoding range reaches far beyond the Klass range, since the class space is just 1GB.
----
The error in this case, introduced with 8338526, was that we use the range `[<encoding base> ... <klass range end>)` for `is_in_encodable_range()`. That can lead to false positives. Since the base can be zero, a non-class Metaspage region may live in address regions below the Klass range (between `0` and `<klass range start>`). A Klass in that region would falsely be recognized as "is encodable" even though it lives not in the klass range.
The error is extremely unlikely to happen, mostly because non-class Metaspace regions - freely placed by the OS - typically live in high-address ranges far beyond a low-placed class space, and also it is restricted to zero-based encoding which is only used if CDS is disabled.
- relates to
-
JDK-8340230 Tests crash: assert(is_in_encoding_range || k->is_interface() || k->is_abstract()) failed: sanity
- Resolved
-
JDK-8338526 Don't store abstract and interface Klasses in class metaspace
- Resolved
- links to
-
Commit(master) openjdk/jdk/7849f252
-
Review(master) openjdk/jdk/21015