src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DataSection.java
Print this page
@@ -139,11 +139,11 @@
}
}
private final ArrayList<Data> dataItems = new ArrayList<>();
- private boolean finalLayout;
+ private boolean closed;
private int sectionAlignment;
private int sectionSize;
@Override
public int hashCode() {
@@ -161,26 +161,26 @@
if (this == obj) {
return true;
}
if (obj instanceof DataSection) {
DataSection that = (DataSection) obj;
- if (this.finalLayout == that.finalLayout && this.sectionAlignment == that.sectionAlignment && this.sectionSize == that.sectionSize && Objects.equals(this.dataItems, that.dataItems)) {
+ if (this.closed == that.closed && this.sectionAlignment == that.sectionAlignment && this.sectionSize == that.sectionSize && Objects.equals(this.dataItems, that.dataItems)) {
return true;
}
}
return false;
}
/**
- * Insert a {@link Data} item into the data section. If the item is already in the data section,
- * the same {@link DataSectionReference} is returned.
+ * Inserts a {@link Data} item into the data section. If the item is already in the data
+ * section, the same {@link DataSectionReference} is returned.
*
* @param data the {@link Data} item to be inserted
* @return a unique {@link DataSectionReference} identifying the {@link Data} item
*/
public DataSectionReference insertData(Data data) {
- assert !finalLayout;
+ checkOpen();
synchronized (data) {
if (data.ref == null) {
data.ref = new DataSectionReference();
dataItems.add(data);
}
@@ -191,26 +191,35 @@
/**
* Transfers all {@link Data} from the provided other {@link DataSection} to this
* {@link DataSection}, and empties the other section.
*/
public void addAll(DataSection other) {
- assert !finalLayout && !other.finalLayout;
+ checkOpen();
+ other.checkOpen();
for (Data data : other.dataItems) {
assert data.ref != null;
dataItems.add(data);
}
other.dataItems.clear();
}
/**
- * Compute the layout of the data section. This can be called only once, and after it has been
- * called, the data section can no longer be modified.
+ * Determines if this object has been {@link #close() closed}.
*/
- public void finalizeLayout() {
- assert !finalLayout;
- finalLayout = true;
+ public boolean closed() {
+ return closed;
+ }
+
+ /**
+ * Computes the layout of the data section and closes this object to further updates.
+ *
+ * This must be called exactly once.
+ */
+ void close() {
+ checkOpen();
+ closed = true;
// simple heuristic: put items with larger alignment requirement first
dataItems.sort((a, b) -> a.alignment - b.alignment);
int position = 0;
@@ -225,41 +234,42 @@
sectionAlignment = alignment;
sectionSize = position;
}
- public boolean isFinalized() {
- return finalLayout;
- }
-
/**
- * Get the size of the data section. Can only be called after {@link #finalizeLayout}.
+ * Gets the size of the data section.
+ *
+ * This must only be called once this object has been {@linkplain #closed() closed}.
*/
public int getSectionSize() {
- assert finalLayout;
+ checkClosed();
return sectionSize;
}
/**
- * Get the minimum alignment requirement of the data section. Can only be called after
- * {@link #finalizeLayout}.
+ * Gets the minimum alignment requirement of the data section.
+ *
+ * This must only be called once this object has been {@linkplain #closed() closed}.
*/
public int getSectionAlignment() {
- assert finalLayout;
+ checkClosed();
return sectionAlignment;
}
/**
- * Build the data section. Can only be called after {@link #finalizeLayout}.
+ * Builds the data section into a given buffer.
+ *
+ * This must only be called once this object has been {@linkplain #closed() closed}.
*
- * @param buffer The {@link ByteBuffer} where the data section should be built. The buffer must
+ * @param buffer the {@link ByteBuffer} where the data section should be built. The buffer must
* hold at least {@link #getSectionSize()} bytes.
- * @param patch A {@link Consumer} to receive {@link DataPatch data patches} for relocations in
- * the data section.
+ * @param patch a {@link Consumer} to receive {@link DataPatch data patches} for relocations in
+ * the data section
*/
public void buildDataSection(ByteBuffer buffer, Consumer<DataPatch> patch) {
- assert finalLayout;
+ checkClosed();
for (Data d : dataItems) {
buffer.position(d.ref.getOffset());
d.builder.emit(buffer, patch);
}
}
@@ -298,12 +308,24 @@
private static int align(int position, int alignment) {
return ((position + alignment - 1) / alignment) * alignment;
}
+ private void checkClosed() {
+ if (!closed) {
+ throw new IllegalStateException();
+ }
+ }
+
+ private void checkOpen() {
+ if (closed) {
+ throw new IllegalStateException();
+ }
+ }
+
public void clear() {
- assert !finalLayout;
+ checkOpen();
this.dataItems.clear();
this.sectionAlignment = 0;
this.sectionSize = 0;
}
}