< prev index next > src/java.base/share/classes/jdk/internal/classfile/impl/BufWriterImpl.java
Print this page
* questions.
*/
package jdk.internal.classfile.impl;
import java.lang.classfile.BufWriter;
+ import java.lang.classfile.ClassModel;
import java.lang.classfile.constantpool.ClassEntry;
import java.lang.classfile.constantpool.ConstantPool;
import java.lang.classfile.constantpool.ConstantPoolBuilder;
import java.lang.classfile.constantpool.PoolEntry;
import java.util.Arrays;
+ import java.util.HashSet;
import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.vm.annotation.ForceInline;
+ import static java.lang.classfile.ClassFile.ACC_STATIC;
+ import static java.lang.classfile.ClassFile.ACC_STRICT;
import static java.lang.classfile.constantpool.PoolEntry.TAG_UTF8;
import static jdk.internal.util.ModifiedUtf.putChar;
import static jdk.internal.util.ModifiedUtf.utfLen;
public final class BufWriterImpl implements BufWriter {
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
private final ConstantPoolBuilder constantPool;
private final ClassFileImpl context;
private LabelContext labelContext;
+ private WritableField.UnsetField[] strictInstanceFields; // do not modify array contents
+ private ClassModel lastStrictCheckClass; // buf writer has short life, so do not need weak here
+ private boolean lastStrictCheckResult;
private boolean labelsMatch;
private final ClassEntry thisClass;
private final int majorVersion;
byte[] elems;
int offset = 0;
elems = new byte[initialSize];
this.thisClass = thisClass;
this.majorVersion = majorVersion;
}
+ public boolean strictFieldsMatch(ClassModel cm) {
+ // We have a cache because this check will be called multiple times
+ // if a MethodModel is sent wholesale
+ if (lastStrictCheckClass == cm) {
+ return lastStrictCheckResult;
+ }
+
+ var result = doStrictFieldsMatchCheck(cm);
+ lastStrictCheckClass = cm;
+ lastStrictCheckResult = result;
+ return result;
+ }
+
+ private boolean doStrictFieldsMatchCheck(ClassModel cm) {
+ // TODO only check for preview class files?
+ // UTF8 Entry can be used as equality objects
+ var checks = new HashSet<>(Arrays.asList(getStrictInstanceFields()));
+ for (var f : cm.fields()) {
+ if ((f.flags().flagsMask() & (ACC_STATIC | ACC_STRICT)) == ACC_STRICT) {
+ if (!checks.remove(new WritableField.UnsetField(f.fieldName(), f.fieldType()))) {
+ return false; // Field mismatch!
+ }
+ }
+ }
+ return checks.isEmpty();
+ }
+
@Override
public ConstantPoolBuilder constantPool() {
return constantPool;
}
public void setLabelContext(LabelContext labelContext, boolean labelsMatch) {
this.labelContext = labelContext;
this.labelsMatch = labelsMatch;
}
+ public WritableField.UnsetField[] getStrictInstanceFields() {
+ assert strictInstanceFields != null : "should access only after setter call in DirectClassBuilder";
+ return strictInstanceFields;
+ }
+
+ public void setStrictInstanceFields(WritableField.UnsetField[] strictInstanceFields) {
+ this.strictInstanceFields = strictInstanceFields;
+ }
+
+
public boolean labelsMatch(LabelContext lc) {
return labelsMatch
&& labelContext instanceof DirectCodeBuilder dcb
&& dcb.original == lc;
}
< prev index next >