< prev index next > src/java.base/share/classes/jdk/internal/classfile/impl/BufWriterImpl.java
Print this page
/*
- * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* 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 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) {
this.labelContext = labelContext;
}
+
+ 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;
+ }
+
@Override
public boolean canWriteDirect(ConstantPool other) {
return constantPool.canWriteDirect(other);
}
< prev index next >