If a class file's constant pool contains a Dynamic entry then when the class is initialized a bit is set in the constant pool structure noting that there exists such an entry. See classfileParser.cpp#566. This bit is required for JVMCI to function correctly (specific details as to why this is required are not clear to me).
If the class file is an interface with default methods that are overpass methods then HotSpot rewrites the constant pool structure adjusting entries related to those overpass methods. See the method defaultMethods.cpp:switchover_constant_pool which calls BytecodeConstantPool::create_constant_pool. That latter method does not preserve the bit noting that there exists a Dynamic entry.
To reproduce clone the amber repo, switch to the condy-folding branch, and build a fastdebug build. The following simple program will cause HotSpot to crash
mport java.time.*;
import java.time.chrono.*;
import java.time.format.*;
import java.time.temporal.*;
import java.time.zone.*;
import java.util.List;
public class A {
public static void main(String[] args) throws Exception {
String[] l = new String[] {
"java.time.chrono.ChronoLocalDate"
};
for (String c : l) {
Class.forName(c);
}
}
}
The following patch fixes the issue:
diff -r f6a1ff6755b3 src/hotspot/share/classfile/bytecodeAssembler.cpp
--- a/src/hotspot/share/classfile/bytecodeAssembler.cpp Wed Mar 07 16:34:02 2018 -0500
+++ b/src/hotspot/share/classfile/bytecodeAssembler.cpp Thu Mar 08 08:24:59 2018 -0800
@@ -55,6 +55,10 @@
cp->set_pool_holder(_orig->pool_holder());
_orig->copy_cp_to(1, _orig->length() - 1, cp, 1, CHECK_NULL);
+ if (_orig->has_dynamic_constant()) {
+ cp->set_has_dynamic_constant();
+ }
+
for (int i = 0; i < _entries.length(); ++i) {
BytecodeCPEntry entry = _entries.at(i);
int idx = i + _orig->length();
If the class file is an interface with default methods that are overpass methods then HotSpot rewrites the constant pool structure adjusting entries related to those overpass methods. See the method defaultMethods.cpp:switchover_constant_pool which calls BytecodeConstantPool::create_constant_pool. That latter method does not preserve the bit noting that there exists a Dynamic entry.
To reproduce clone the amber repo, switch to the condy-folding branch, and build a fastdebug build. The following simple program will cause HotSpot to crash
mport java.time.*;
import java.time.chrono.*;
import java.time.format.*;
import java.time.temporal.*;
import java.time.zone.*;
import java.util.List;
public class A {
public static void main(String[] args) throws Exception {
String[] l = new String[] {
"java.time.chrono.ChronoLocalDate"
};
for (String c : l) {
Class.forName(c);
}
}
}
The following patch fixes the issue:
diff -r f6a1ff6755b3 src/hotspot/share/classfile/bytecodeAssembler.cpp
--- a/src/hotspot/share/classfile/bytecodeAssembler.cpp Wed Mar 07 16:34:02 2018 -0500
+++ b/src/hotspot/share/classfile/bytecodeAssembler.cpp Thu Mar 08 08:24:59 2018 -0800
@@ -55,6 +55,10 @@
cp->set_pool_holder(_orig->pool_holder());
_orig->copy_cp_to(1, _orig->length() - 1, cp, 1, CHECK_NULL);
+ if (_orig->has_dynamic_constant()) {
+ cp->set_has_dynamic_constant();
+ }
+
for (int i = 0; i < _entries.length(); ++i) {
BytecodeCPEntry entry = _entries.at(i);
int idx = i + _orig->length();