/*
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. 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
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.objectfile;
import java.util.ArrayList;
import java.util.List;
public final class LayoutDecision implements Comparable<LayoutDecision> {
public enum Kind {
NOTE that offsets are only useful as WriteLayoutDecisions, not ReadLayoutDecisions,
because we store ReadLayoutDecisions in a FileLayout, where they are keyed on offset,
i.e. the offset is already known and is stored outside the LayoutDecision.
/**
* NOTE that offsets are only useful as WriteLayoutDecisions, not ReadLayoutDecisions,
* because we store ReadLayoutDecisions in a FileLayout, where they are keyed on offset,
* i.e. the offset is already known and is stored outside the LayoutDecision.
*/
OFFSET,
SIZE,
CONTENT,
IDENTITY,
VADDR,
}
private final Kind kind;
private final ObjectFile.Element element;
private final List<LayoutDecision> dependsOn;
private final List<LayoutDecision> dependedOnBy;
private Object value;
LayoutDecision(Kind kind, ObjectFile.Element element, Object value) {
dependsOn = new ArrayList<>();
dependedOnBy = new ArrayList<>();
this.kind = kind;
// assert element != null;
this.element = element;
assert !(value instanceof LayoutDecision);
this.value = value;
}
@Override
public String toString() {
return "LayoutDecision(" + element + ", " + kind + ", " + value + ")";
}
List<LayoutDecision> dependedOnBy() {
return dependedOnBy;
}
List<LayoutDecision> dependsOn() {
return dependsOn;
}
Kind getKind() {
return kind;
}
void setValue(Object value) {
assert this.value == null; // can't re-set
assert value instanceof Integer || value instanceof byte[];
this.value = value;
}
public Object getValue() {
return value;
}
public boolean isTaken() {
return value != null;
}
public ObjectFile.Element getElement() {
return element;
}
@Override
public int compareTo(LayoutDecision arg) {
ObjectFile.Element ourElement = getElement();
int ourElementIndex = ourElement == null ? -1 : ourElement.getOwner().getElements().indexOf(ourElement);
int ourKindOrdinal = getKind().ordinal();
ObjectFile.Element argElement = arg.getElement();
int argElementIndex = argElement == null ? -1 : argElement.getOwner().getElements().indexOf(argElement);
int argKindOrdinal = arg.getKind().ordinal();
// we can only compare decisions about the same object file
if (ourElement != null && argElement != null && ourElement.getOwner() != argElement.getOwner()) {
throw new IllegalArgumentException("cannot compare decisions across object files");
}
if (ourElementIndex < argElementIndex) {
return -1;
} else if (ourElementIndex > argElementIndex) {
return 1;
} else {
if (ourKindOrdinal < argKindOrdinal) {
return -1;
} else if (ourKindOrdinal > argKindOrdinal) {
return 1;
} else {
return 0;
}
}
}
}