diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/BlockWriter.java b/com.amd.aparapi/src/java/com/amd/aparapi/BlockWriter.java index 4f4c097b74bffd89176a14d81c3dd6aefa0b1170..f1d66aa32206c7ce8cab44f9734ee9c7f5c3020d 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/BlockWriter.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/BlockWriter.java @@ -42,8 +42,8 @@ import java.util.Stack; import com.amd.aparapi.BranchSet.CompoundLogicalExpressionNode; import com.amd.aparapi.BranchSet.LogicalExpressionNode; import com.amd.aparapi.BranchSet.SimpleLogicalExpressionNode; -import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry.LocalVariableInfo; import com.amd.aparapi.ClassModel.ConstantPool.MethodEntry; +import com.amd.aparapi.ClassModel.LocalVariableInfo; import com.amd.aparapi.InstructionSet.AccessArrayElement; import com.amd.aparapi.InstructionSet.AccessField; import com.amd.aparapi.InstructionSet.AccessInstanceField; diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/ClassModel.java b/com.amd.aparapi/src/java/com/amd/aparapi/ClassModel.java index ea7520bcf89aca66b3a0ac82295554ab3e2c5338..a4ccc41c21258b544984443ea5d4f055c4035ff3 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/ClassModel.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/ClassModel.java @@ -46,7 +46,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import com.amd.aparapi.ClassModel.AttributePool.CodeEntry; -import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry; import com.amd.aparapi.ClassModel.ConstantPool.FieldEntry; import com.amd.aparapi.ClassModel.ConstantPool.MethodEntry; import com.amd.aparapi.InstructionSet.TypeSpec; @@ -66,6 +65,27 @@ import com.amd.aparapi.InstructionSet.TypeSpec; */ class ClassModel{ + interface LocalVariableInfo{ + + int getStart(); + + boolean isArray(); + + int getEnd(); + + String getVariableName(); + + String getVariableDescriptor(); + + int getVariableIndex(); + + } + + interface LocalVariableTableEntry<T extends LocalVariableInfo> extends Iterable<T>{ + LocalVariableInfo getVariable(int _pc, int _index); + + } + static final char SIGC_VOID = 'V'; static final char SIGC_BOOLEAN = 'Z'; @@ -1706,9 +1726,10 @@ class ClassModel{ } - class LocalVariableTableEntry extends PoolEntry<LocalVariableTableEntry.LocalVariableInfo>{ + class RealLocalVariableTableEntry extends PoolEntry<RealLocalVariableTableEntry.RealLocalVariableInfo> implements + LocalVariableTableEntry<RealLocalVariableTableEntry.RealLocalVariableInfo>{ - class LocalVariableInfo{ + class RealLocalVariableInfo implements LocalVariableInfo{ private int descriptorIndex; private int usageLength; @@ -1719,7 +1740,7 @@ class ClassModel{ private int variableIndex; - LocalVariableInfo(ByteReader _byteReader) { + RealLocalVariableInfo(ByteReader _byteReader) { start = _byteReader.u2(); usageLength = _byteReader.u2(); variableNameIndex = _byteReader.u2(); @@ -1739,39 +1760,43 @@ class ClassModel{ return (variableNameIndex); } - int getStart() { + @Override public int getStart() { return (start); } - int getVariableIndex() { + @Override public int getVariableIndex() { return (variableIndex); } - String getVariableName() { + @Override public String getVariableName() { return (constantPool.getUTF8Entry(variableNameIndex).getUTF8()); } - String getVariableDescriptor() { + @Override public String getVariableDescriptor() { return (constantPool.getUTF8Entry(descriptorIndex).getUTF8()); } - int getEnd() { + @Override public int getEnd() { return (start + usageLength); } + + @Override public boolean isArray() { + return (getVariableDescriptor().startsWith("[")); + } } - LocalVariableTableEntry(ByteReader _byteReader, int _nameIndex, int _length) { + RealLocalVariableTableEntry(ByteReader _byteReader, int _nameIndex, int _length) { super(_byteReader, _nameIndex, _length); int localVariableTableLength = _byteReader.u2(); for (int i = 0; i < localVariableTableLength; i++) { - getPool().add(new LocalVariableInfo(_byteReader)); + getPool().add(new RealLocalVariableInfo(_byteReader)); } } - LocalVariableInfo getVariable(int _pc, int _index) { - LocalVariableInfo returnValue = null; + public LocalVariableInfo getVariable(int _pc, int _index) { + RealLocalVariableInfo returnValue = null; // System.out.println("pc = " + _pc + " index = " + _index); - for (LocalVariableInfo localVariableInfo : getPool()) { + for (RealLocalVariableInfo localVariableInfo : getPool()) { // System.out.println(" start=" + localVariableInfo.getStart() + " length=" + localVariableInfo.getLength() // + " varidx=" + localVariableInfo.getVariableIndex()); if (_pc >= localVariableInfo.getStart() - 1 && _pc <= (localVariableInfo.getStart() + localVariableInfo.getLength()) @@ -1786,7 +1811,7 @@ class ClassModel{ String getVariableName(int _pc, int _index) { String returnValue = "unknown"; - LocalVariableInfo localVariableInfo = getVariable(_pc, _index); + RealLocalVariableInfo localVariableInfo = (RealLocalVariableInfo) getVariable(_pc, _index); if (localVariableInfo != null) { returnValue = convert(constantPool.getUTF8Entry(localVariableInfo.getDescriptorIndex()).getUTF8(), constantPool .getUTF8Entry(localVariableInfo.getNameIndex()).getUTF8()); @@ -1861,6 +1886,23 @@ class ClassModel{ } + class StackMapTableEntry extends AttributePoolEntry{ + private byte[] bytes; + + StackMapTableEntry(ByteReader _byteReader, int _nameIndex, int _length) { + super(_byteReader, _nameIndex, _length); + bytes = _byteReader.bytes(_length); + } + + byte[] getBytes() { + return (bytes); + } + + @Override public String toString() { + return (new String(bytes)); + } + } + class SourceFileEntry extends AttributePoolEntry{ private int sourceFileIndex; @@ -2069,6 +2111,8 @@ class ClassModel{ private final static String BOOTSTRAPMETHODS_TAG = "BootstrapMethods"; + private final static String STACKMAPTABLE_TAG = "StackMapTable"; + AttributePool(ByteReader _byteReader) { int attributeCount = _byteReader.u2(); @@ -2078,8 +2122,8 @@ class ClassModel{ int length = _byteReader.u4(); String attributeName = constantPool.getUTF8Entry(attributeNameIndex).getUTF8(); if (attributeName.equals(LOCALVARIABLETABLE_TAG)) { - localVariableTableEntry = new LocalVariableTableEntry(_byteReader, attributeNameIndex, length); - entry = localVariableTableEntry; + localVariableTableEntry = new RealLocalVariableTableEntry(_byteReader, attributeNameIndex, length); + entry = (RealLocalVariableTableEntry) localVariableTableEntry; } else if (attributeName.equals(CONSTANTVALUE_TAG)) { entry = new ConstantValueEntry(_byteReader, attributeNameIndex, length); } else if (attributeName.equals(LINENUMBERTABLE_TAG)) { @@ -2117,12 +2161,17 @@ class ClassModel{ bootstrapMethodsEntry = new BootstrapMethodsEntry(_byteReader, attributeNameIndex, length); entry = bootstrapMethodsEntry; // http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.21 + } else if (attributeName.equals(STACKMAPTABLE_TAG)) { + // http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.4 + + entry = new StackMapTableEntry(_byteReader, attributeNameIndex, length); } else { System.out.println("Other! found (name = " + attributeName + ")"); entry = new OtherEntry(_byteReader, attributeNameIndex, length); + attributePoolEntries.add(entry); } - attributePoolEntries.add(entry); } + } CodeEntry getCodeEntry() { @@ -2311,11 +2360,11 @@ class ClassModel{ return (getAttributePool().codeEntry.codeEntryAttributePool.lineNumberTableEntry); } - AttributePool.LocalVariableTableEntry getLocalVariableTableEntry() { + LocalVariableTableEntry getLocalVariableTableEntry() { return (getAttributePool().codeEntry.codeEntryAttributePool.localVariableTableEntry); } - LocalVariableTableEntry.LocalVariableInfo getLocalVariable(int _pc, int _index) { + LocalVariableInfo getLocalVariable(int _pc, int _index) { return (getLocalVariableTableEntry().getVariable(_pc, _index)); } diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/ClassParseException.java b/com.amd.aparapi/src/java/com/amd/aparapi/ClassParseException.java index cbf564ea13fe5a329a64e10f26d00450c677dfcd..c375baff4d97aab85200c6ca492ab9308d9834c8 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/ClassParseException.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/ClassParseException.java @@ -79,7 +79,7 @@ package com.amd.aparapi; ACCESSEDOBJECTONLYSUPPORTSSIMPLEPUTFIELD("We don't support putfield instructions beyond simple setters"), // ACCESSEDOBJECTSETTERARRAY("Passing array arguments to Intrinsics in expression form is not supported"), // MULTIDIMENSIONARRAYASSIGN("Can't assign to two dimension array"), // - MULTIDIMENSIONARRAYACCESS("Can't access through a two dimensional array"),// + MULTIDIMENSIONARRAYACCESS("Can't access through a two dimensional array"), // MISSINGLOCALVARIABLETABLE("Method does not contain a local variable table (recompile with -g?)"); private String description; diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/ExpressionList.java b/com.amd.aparapi/src/java/com/amd/aparapi/ExpressionList.java index 98507fcdfdd8ef99c067422ff7fb1668a151f065..79a39e4f8db6bbfbcd584e9adb5165456cc8e133 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/ExpressionList.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/ExpressionList.java @@ -43,8 +43,8 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry; -import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry.LocalVariableInfo; +import com.amd.aparapi.ClassModel.LocalVariableInfo; +import com.amd.aparapi.ClassModel.LocalVariableTableEntry; import com.amd.aparapi.InstructionSet.AssignToLocalVariable; import com.amd.aparapi.InstructionSet.Branch; import com.amd.aparapi.InstructionSet.ByteCode; @@ -755,12 +755,12 @@ class ExpressionList{ } else { // might be end of arbitrary scope - LocalVariableTableEntry localVariableTable = methodModel.getMethod().getLocalVariableTableEntry(); + LocalVariableTableEntry<LocalVariableInfo> localVariableTable = methodModel.getMethod().getLocalVariableTableEntry(); int startPc = Short.MAX_VALUE; if (Config.enableAllowMissingLocalVariableTable && localVariableTable == null) { logger.warning("class does not contain a LocalVariableTable - but enableAllowMissingLocalVariableTable is set so we are ignoring"); } else { - for (LocalVariableInfo localVariableInfo : localVariableTable.getPool()) { + for (LocalVariableInfo localVariableInfo : localVariableTable) { if (localVariableInfo.getEnd() == _instruction.getThisPC()) { logger.fine(localVariableInfo.getVariableName() + " scope " + localVariableInfo.getStart() + " ," diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/InstructionHelper.java b/com.amd.aparapi/src/java/com/amd/aparapi/InstructionHelper.java index 4d4b581ee1eb9e1af8fdec73a641932bfed092f6..02df39202b890d2c91815004c9e2051d8596b135 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/InstructionHelper.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/InstructionHelper.java @@ -5,7 +5,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; -import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry.LocalVariableInfo; +import com.amd.aparapi.ClassModel.LocalVariableInfo; import com.amd.aparapi.InstructionSet.AssignToLocalVariable; import com.amd.aparapi.InstructionSet.Branch; import com.amd.aparapi.InstructionSet.ByteCode; diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/InstructionSet.java b/com.amd.aparapi/src/java/com/amd/aparapi/InstructionSet.java index 2ba8b59d051b211d146bc1b01ca6c6427012404a..a9777fa033ae49b47d32989e270febc577a5cdcc 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/InstructionSet.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/InstructionSet.java @@ -40,12 +40,12 @@ package com.amd.aparapi; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry; -import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry.LocalVariableInfo; import com.amd.aparapi.ClassModel.ConstantPool; import com.amd.aparapi.ClassModel.ConstantPool.Entry; import com.amd.aparapi.ClassModel.ConstantPool.FieldEntry; import com.amd.aparapi.ClassModel.ConstantPool.MethodEntry; +import com.amd.aparapi.ClassModel.LocalVariableInfo; +import com.amd.aparapi.ClassModel.LocalVariableTableEntry; class InstructionSet{ diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/KernelWriter.java b/com.amd.aparapi/src/java/com/amd/aparapi/KernelWriter.java index e11f1ff1bb0bae90fb4dcba429d3acccbcfc138e..ef9146b62da9fce379f252e658939f72ee1d763e 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/KernelWriter.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/KernelWriter.java @@ -43,13 +43,13 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry; -import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry.LocalVariableInfo; import com.amd.aparapi.ClassModel.AttributePool.RuntimeAnnotationsEntry; import com.amd.aparapi.ClassModel.AttributePool.RuntimeAnnotationsEntry.AnnotationInfo; import com.amd.aparapi.ClassModel.ClassModelField; import com.amd.aparapi.ClassModel.ConstantPool.FieldEntry; import com.amd.aparapi.ClassModel.ConstantPool.MethodEntry; +import com.amd.aparapi.ClassModel.LocalVariableInfo; +import com.amd.aparapi.ClassModel.LocalVariableTableEntry; import com.amd.aparapi.InstructionSet.AccessArrayElement; import com.amd.aparapi.InstructionSet.AssignToArrayElement; import com.amd.aparapi.InstructionSet.AssignToField; @@ -523,7 +523,7 @@ abstract class KernelWriter extends BlockWriter{ boolean alreadyHasFirstArg = !mm.getMethod().isStatic(); - LocalVariableTableEntry lvte = mm.getLocalVariableTableEntry(); + LocalVariableTableEntry<LocalVariableInfo> lvte = mm.getLocalVariableTableEntry(); for (LocalVariableInfo lvi : lvte) { if ((lvi.getStart() == 0) && ((lvi.getVariableIndex() != 0) || mm.getMethod().isStatic())) { // full scope but skip this String descriptor = lvi.getVariableDescriptor(); diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/MethodModel.java b/com.amd.aparapi/src/java/com/amd/aparapi/MethodModel.java index be1c8f3ec5b07e9c72ef833fe7d60720dc5dc6f8..a3948c075b560fbe685cc0d4e602ab02fcab55e1 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/MethodModel.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/MethodModel.java @@ -49,13 +49,13 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry; -import com.amd.aparapi.ClassModel.AttributePool.LocalVariableTableEntry.LocalVariableInfo; import com.amd.aparapi.ClassModel.ClassModelMethod; import com.amd.aparapi.ClassModel.ConstantPool; import com.amd.aparapi.ClassModel.ConstantPool.FieldEntry; import com.amd.aparapi.ClassModel.ConstantPool.MethodReferenceEntry; import com.amd.aparapi.ClassModel.ConstantPool.MethodReferenceEntry.Arg; +import com.amd.aparapi.ClassModel.LocalVariableInfo; +import com.amd.aparapi.ClassModel.LocalVariableTableEntry; import com.amd.aparapi.InstructionPattern.InstructionMatch; import com.amd.aparapi.InstructionSet.AccessArrayElement; import com.amd.aparapi.InstructionSet.AccessField; @@ -1468,26 +1468,28 @@ class MethodModel{ // check if we have any local variables which are arrays. This is an attempt to avoid aliasing field arrays - LocalVariableTableEntry localVariableTableEntry = method.getLocalVariableTableEntry(); + // We are going to make 4 passes. + + // Pass #1 create a linked list of instructions from head to tail + Map<Integer, Instruction> pcMap = createListOfInstructions(); + + LocalVariableTableEntry<LocalVariableInfo> localVariableTableEntry = method.getLocalVariableTableEntry(); if (Config.enableAllowMissingLocalVariableTable && localVariableTableEntry == null) { logger.warning("class does not contain a LocalVariableTable - but enableAllowMissingLocalVariableTable is set so we are ignoring"); } else { - if (localVariableTableEntry == null){ + if (localVariableTableEntry == null) { + System.out.println("create local variable table"); throw new ClassParseException(ClassParseException.TYPE.MISSINGLOCALVARIABLETABLE); } for (LocalVariableInfo localVariableInfo : localVariableTableEntry) { + // TODO: What was the thinking here? final boolean DISALLOWARRAYLOCALVAR = false; - if (DISALLOWARRAYLOCALVAR && localVariableInfo.getVariableDescriptor().startsWith("[")) { + if (DISALLOWARRAYLOCALVAR && localVariableInfo.isArray()) { throw new ClassParseException(ClassParseException.TYPE.ARRAYLOCALVARIABLE); } } } - // We are going to make 4 passes. - - // Pass #1 create a linked list of instructions from head to tail - Map<Integer, Instruction> pcMap = createListOfInstructions(); - // pass #2 build branch graph buildBranchGraphs(pcMap);