diff options
author | aclement <aclement> | 2005-10-05 12:23:52 +0000 |
---|---|---|
committer | aclement <aclement> | 2005-10-05 12:23:52 +0000 |
commit | 12e6334bf5f77d7c3bc2e66eeefa105f0507334a (patch) | |
tree | 740bd9271abcafb3bad10c01ba3060d8383efce0 /weaver | |
parent | 451fea8a2f9b3640d6c133c3f01dad8b9a78f72c (diff) | |
download | aspectj-12e6334bf5f77d7c3bc2e66eeefa105f0507334a.tar.gz aspectj-12e6334bf5f77d7c3bc2e66eeefa105f0507334a.zip |
Let the bug floodgates open, reweavable is now default (pr91417)
Diffstat (limited to 'weaver')
6 files changed, 297 insertions, 70 deletions
diff --git a/weaver/src/org/aspectj/weaver/WeaverStateInfo.java b/weaver/src/org/aspectj/weaver/WeaverStateInfo.java index 53aa6ffed..ca3fe6356 100644 --- a/weaver/src/org/aspectj/weaver/WeaverStateInfo.java +++ b/weaver/src/org/aspectj/weaver/WeaverStateInfo.java @@ -13,6 +13,8 @@ package org.aspectj.weaver; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -25,12 +27,10 @@ import java.util.List; import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; import org.aspectj.bridge.IMessage; import org.aspectj.weaver.bcel.BcelTypeMunger; - /** * WeaverStateInfo represents how a type was processed. It is used by the weaver to determine how a type * was previously treated and whether reweaving is allowed. @@ -51,31 +51,48 @@ public class WeaverStateInfo { private List/*Entry*/ typeMungers; private boolean oldStyle; - - private boolean reweavable; - private boolean reweavableCompressedMode; // If true, unwovenClassFile is compressed on write and uncompressed on read + private boolean reweavableCompressedMode; // If true, unwovenClassFile is uncompressed on read + private boolean reweavableDiffMode; // if true, unwovenClassFile is written and read as a diff + private Set /*String*/ aspectsAffectingType; // These must exist in the world for reweaving to be valid private byte[] unwovenClassFile; // Original 'untouched' class file - private static boolean reweavableDefault = false; + private static boolean reweavableDefault = true; // ajh02: changed from false; private static boolean reweavableCompressedModeDefault = false; + private static boolean reweavableDiffModeDefault = true; + + // when serializing the WeaverStateInfo we come to adding the reweavable data, + // we'd like to add a diff of the unwovenClassFile and the wovenClassFile, + // but we don't have the wovenClassFile yet as we're still in the process of making it. + // so we put this key there instead as a stub. + // Then when the wovenClassFile has been made, replaceKeyWithDiff is called. + private static byte [] key = { + -51, 34, 105, 56, -34, 65, 45, 78, -26, 125, 114, 97, 98, 1, -1, -42 + }; + private boolean unwovenClassFileIsADiff = false; public WeaverStateInfo() { - this(new ArrayList(), false,reweavableDefault,reweavableCompressedModeDefault); + this(new ArrayList(), false,reweavableDefault,reweavableCompressedModeDefault,reweavableDiffModeDefault); } - private WeaverStateInfo(List typeMungers, boolean oldStyle,boolean reweavableMode,boolean reweavableCompressedMode) { + public WeaverStateInfo(boolean reweavable) { + this(new ArrayList(), false,reweavable,reweavableCompressedModeDefault,reweavableDiffModeDefault); + } + + private WeaverStateInfo(List typeMungers, boolean oldStyle,boolean reweavableMode,boolean reweavableCompressedMode,boolean reweavableDiffMode) { this.typeMungers = typeMungers; this.oldStyle = oldStyle; this.reweavable = reweavableMode; this.reweavableCompressedMode = reweavableCompressedMode; + this.reweavableDiffMode = reweavableMode?reweavableDiffMode:false; this.aspectsAffectingType= new HashSet(); this.unwovenClassFile = null; } - public static void setReweavableModeDefaults(boolean mode, boolean compress) { + public static void setReweavableModeDefaults(boolean mode, boolean compress, boolean diff) { reweavableDefault = mode; reweavableCompressedModeDefault = compress; + reweavableDiffModeDefault = diff; } private static final int UNTOUCHED=0, WOVEN=2, EXTENDED=3; @@ -83,21 +100,32 @@ public class WeaverStateInfo { // Use 'bits' for these capabilities - only valid in EXTENDED mode private static final byte REWEAVABLE_BIT = 1<<4; private static final byte REWEAVABLE_COMPRESSION_BIT = 1<<5; + private static final byte REWEAVABLE_DIFF_BIT = 1<<6; + /** See comments on write() */ public static final WeaverStateInfo read(VersionedDataInputStream s, ISourceContext context) throws IOException { byte b = s.readByte(); boolean isReweavable = ((b&REWEAVABLE_BIT)!=0); - if (isReweavable) b=(byte) (b-REWEAVABLE_BIT); + if (isReweavable){ + b=(byte) (b-REWEAVABLE_BIT); + } boolean isReweavableCompressed = ((b&REWEAVABLE_COMPRESSION_BIT)!=0); - if (isReweavableCompressed) b=(byte) (b-REWEAVABLE_COMPRESSION_BIT); + if (isReweavableCompressed){ + b=(byte) (b-REWEAVABLE_COMPRESSION_BIT); + } + + boolean isReweavableDiff = ((b&REWEAVABLE_DIFF_BIT)!=0); + if (isReweavableDiff){ + b=(byte) (b-REWEAVABLE_DIFF_BIT); + } switch(b) { case UNTOUCHED: throw new RuntimeException("unexpected UNWOVEN"); case WOVEN: - return new WeaverStateInfo(Collections.EMPTY_LIST, true,isReweavable,isReweavableCompressed); + return new WeaverStateInfo(Collections.EMPTY_LIST, true,isReweavable,isReweavableCompressed,isReweavableDiff); case EXTENDED: int n = s.readShort(); List l = new ArrayList(); @@ -107,7 +135,7 @@ public class WeaverStateInfo { ResolvedTypeMunger.read(s, context); l.add(new Entry(aspectType, typeMunger)); } - WeaverStateInfo wsi = new WeaverStateInfo(l,false,isReweavable,isReweavableCompressed); + WeaverStateInfo wsi = new WeaverStateInfo(l,false,isReweavable,isReweavableCompressed,isReweavableDiff); readAnyReweavableData(wsi,s); return wsi; } @@ -129,13 +157,28 @@ public class WeaverStateInfo { } } + /** + * Serialize the WeaverStateInfo. Various bits are set within the 'kind' flag to indicate the structure of + * the attribute. In reweavable diff mode a 'marker' is inserted at the start of the attribute to indicate + * where the final calculated diff should be inserted. When the key is replaced with the diff, the 'kind' + * byte moves to the front of the attribute - thats why in the read logic you'll see it expecting the + * kind as the first byte. + */ public void write(DataOutputStream s) throws IOException { - if (oldStyle) throw new RuntimeException("shouldn't be writing this"); + if (oldStyle || reweavableCompressedMode) { + throw new RuntimeException("shouldn't be writing this"); + } byte weaverStateInfoKind = EXTENDED; if (reweavable) weaverStateInfoKind |= REWEAVABLE_BIT; - if (reweavableCompressedMode) weaverStateInfoKind |= REWEAVABLE_COMPRESSION_BIT; + + if (reweavableDiffMode){ + s.write(key); // put key in so we can replace it with the diff later + weaverStateInfoKind |= REWEAVABLE_DIFF_BIT; + } + s.writeByte(weaverStateInfoKind); + int n = typeMungers.size(); s.writeShort(n); for (int i=0; i < n; i++) { @@ -176,10 +219,14 @@ public class WeaverStateInfo { public boolean isOldStyle() { return oldStyle; } - - public byte[] getUnwovenClassFileData() { + + public byte[] getUnwovenClassFileData(byte wovenClassFile[]) { + if (unwovenClassFileIsADiff){ + unwovenClassFile = applyDiff(wovenClassFile, unwovenClassFile); + unwovenClassFileIsADiff = false; + } return unwovenClassFile; - } + } public void setUnwovenClassFileData(byte[] data) { unwovenClassFile = data; @@ -189,9 +236,8 @@ public class WeaverStateInfo { return reweavable; } - public void setReweavable(boolean rw,boolean compressData) { + public void setReweavable(boolean rw) { reweavable = rw; - reweavableCompressedMode = compressData; } public void addAspectsAffectingType(Collection /*String*/ aspects) { @@ -204,11 +250,8 @@ public class WeaverStateInfo { return this.aspectsAffectingType; } - - //// - + private static void readAnyReweavableData(WeaverStateInfo wsi,DataInputStream s) throws IOException { - if (wsi.isReweavable()) { // Load list of aspects that need to exist in the world for reweaving to be 'legal' int numberAspectsAffectingType = s.readShort(); @@ -216,18 +259,9 @@ public class WeaverStateInfo { int unwovenClassFileSize = s.readInt(); byte[] classData = null; - // The data might or might not be compressed: - if (!wsi.reweavableCompressedMode) { - // Read it straight in - classData = new byte[unwovenClassFileSize]; - int bytesread = s.read(classData); - if (bytesread!=unwovenClassFileSize) - throw new IOException("ERROR whilst reading reweavable data, expected "+ - unwovenClassFileSize+" bytes, only found "+bytesread); - } else { - // Decompress it - classData = new byte[unwovenClassFileSize]; - + // the unwovenClassFile may have been compressed: + if (wsi.reweavableCompressedMode) { + classData = new byte[unwovenClassFileSize]; ZipInputStream zis = new ZipInputStream(s); ZipEntry zen = zis.getNextEntry(); int current = 0; @@ -239,13 +273,191 @@ public class WeaverStateInfo { } zis.closeEntry(); if (bytesToGo!=0) - throw new IOException("ERROR whilst reading compressed reweavable data, expected "+ - unwovenClassFileSize+" bytes, only found "+current); + throw new IOException("ERROR whilst reading compressed reweavable data, expected "+ + unwovenClassFileSize+" bytes, only found "+current); + } else { + classData = new byte[unwovenClassFileSize]; + int bytesread = s.read(classData); + if (bytesread!=unwovenClassFileSize) + throw new IOException("ERROR whilst reading reweavable data, expected "+ + unwovenClassFileSize+" bytes, only found "+bytesread); } + + // if it was diffMode we'll have to remember to apply the diff if someone + // asks for the unwovenClassFile + wsi.unwovenClassFileIsADiff = wsi.reweavableDiffMode; wsi.setUnwovenClassFileData(classData); } } + /** + * Here is the cleverness for reweavable diff mode. The class file on disk contains, inside the weaverstateinfo attribute, a diff + * that can be applied to 'itself' to recover the original class - which can then be rewoven. + */ + public byte[] replaceKeyWithDiff(byte wovenClassFile[]) { + // we couldn't have made the diff earlier + // as we didn't have the wovenClassFile + // so we left a key there as a marker to come back to + + if (reweavableDiffMode){ + ByteArrayOutputStream arrayStream = new ByteArrayOutputStream(); + DataOutputStream s = new DataOutputStream(arrayStream); + + int endOfKey = findEndOfKey(wovenClassFile); + int startOfKey = endOfKey - key.length; + // the length of the wsi attribute is written infront of it in the classFile, + // swapping the diff for the key will probably change the length of the wsi, + // so we'll have to fiddle with the four 'int length' bytes + int oldLengthLocation = startOfKey -4; + int oldLength = readInt(wovenClassFile, oldLengthLocation); + wovenClassFile = deleteInArray(wovenClassFile,startOfKey,endOfKey); // delete the key + + byte [] wovenClassFileUpToWSI = new byte [oldLengthLocation]; + System.arraycopy(wovenClassFile,0,wovenClassFileUpToWSI,0,oldLengthLocation); + + byte [] diff = generateDiff(wovenClassFileUpToWSI, unwovenClassFile); + try { // put the length of the diff infront of the diff + s.writeInt(diff.length); + s.write(diff); + } catch(IOException e){} + diff = arrayStream.toByteArray(); + // we have to swap the oldLength for the new one, + // and add the diff, using the oldLength to work out where it should go :) + + int newLength = oldLength - key.length + diff.length; + byte newLengthBytes[] = serializeInt(newLength); + + // swap in the serialized newLength for the oldOne: + wovenClassFile[oldLengthLocation] = newLengthBytes[0]; + wovenClassFile[oldLengthLocation + 1] = newLengthBytes[1]; + wovenClassFile[oldLengthLocation + 2] = newLengthBytes[2]; + wovenClassFile[oldLengthLocation + 3] = newLengthBytes[3]; + + // add the diff + wovenClassFile = insertArray(diff, wovenClassFile, oldLengthLocation + 4 + oldLength - key.length); + } + return wovenClassFile; + } + + private static final int findEndOfKey(byte [] wovenClassFile){ + // looks through the classfile backwards (as the attributes are all near the end) + for(int i = wovenClassFile.length - 1; i > 0; i--) + if(endOfKeyHere(wovenClassFile, i)){ + return i + 1; + } + throw new RuntimeException("key not found in wovenClassFile"); // should never happen + } + + private static final boolean endOfKeyHere(byte lookIn[], int i){ + for(int j = 0; j < key.length; j++) + if(key[key.length - 1 - j] != lookIn[i - j]){ + return false; + } + return true; + } + private static final byte[] insertArray(byte toInsert[], byte original[], int offset){ + byte result[] = new byte[original.length + toInsert.length]; + System.arraycopy(original, 0, result, 0, offset); + System.arraycopy(toInsert, 0, result, offset, toInsert.length); + System.arraycopy(original, offset, result, offset + toInsert.length, original.length - offset); + return result; + } + private static final int readInt(byte [] a, int offset){ + ByteArrayInputStream b = new ByteArrayInputStream(a, offset, 4); + DataInputStream d = new DataInputStream(b); + int length = -1; + try{ + length = d.readInt(); + } + catch(IOException e) { + throw(new RuntimeException("readInt called with a bad array or offset")); // should never happen + } + return length; + } + private static final byte[] deleteInArray(byte a[], int start, int end){ + int lengthToDelete = end - start; + byte result[] = new byte[a.length - lengthToDelete]; // make a new array + System.arraycopy(a, 0, result, 0, start); // copy in the bit before the deleted bit + System.arraycopy(a, end, result, start, a.length - end); // copy in the bit after the deleted bit + return result; + } + + // ajh02: a quick note about the diff format... + // + // classfiles consist of: + // 8 bytes: magic number and minor and major versions, + // 2 bytes: its constant pool count + // n bytes: the rest of the class file + // + // weaving a classfile never changes the classfile's first 8 bytes, + // and after the constant pool count there's usually a run of bytes that weaving didn't change + // hereafter referred to as the run + // + // so the diff consists of: + // 2 bytes: its constant pool count + // 4 bytes: length of the run + // n bytes: the rest of the unwovenClassFile + + byte [] generateDiff(byte [] wovenClassFile, byte [] unWovenClassFile){ + + // find how long the run is + int lookingAt = 10; + int shorterLength + =(wovenClassFile.length < unWovenClassFile.length)? wovenClassFile.length:unWovenClassFile.length; + while (lookingAt < shorterLength && (wovenClassFile[lookingAt] == unWovenClassFile[lookingAt])){ + lookingAt++; + } + int lengthInCommon = lookingAt - 10; + byte [] diff = new byte [unWovenClassFile.length - 4 - lengthInCommon]; + + // first 2 bytes of the diff are the constant pool count + diff[0] = unWovenClassFile[8]; + diff[1] = unWovenClassFile[9]; + + // then 4 bytes saying how long the run is + byte [] lengthInCommonBytes = serializeInt(lengthInCommon); + diff[2] = lengthInCommonBytes[0]; + diff[3] = lengthInCommonBytes[1]; + diff[4] = lengthInCommonBytes[2]; + diff[5] = lengthInCommonBytes[3]; + + // then we just dump the rest of the unWovenClassFile verbatim + System.arraycopy(unWovenClassFile,10+lengthInCommon,diff,6,diff.length-6); + + return diff; + } + + byte [] applyDiff(byte [] wovenClassFile, byte [] diff){ + + int lengthInCommon = readInt(diff,2); + byte [] unWovenClassFile = new byte [4 + diff.length + lengthInCommon]; + + // copy the first 8 bytes from the wovenClassFile + System.arraycopy(wovenClassFile,0,unWovenClassFile,0,8); + + // copy the constant pool count from the diff + unWovenClassFile[8] = diff[0]; + unWovenClassFile[9] = diff[1]; + + // copy the run from the wovenClassFile + System.arraycopy(wovenClassFile,10,unWovenClassFile,10,lengthInCommon); + + // copy the stuff after the run from the diff + System.arraycopy(diff,6,unWovenClassFile,10+lengthInCommon,diff.length-6); + + return unWovenClassFile; + } + + private byte [] serializeInt(int i){ + ByteArrayOutputStream bos = new ByteArrayOutputStream(4); + DataOutputStream dos = new DataOutputStream(bos); + try { + dos.writeInt(i); + } catch(IOException e) {} + return bos.toByteArray(); + } + + private static void writeAnyReweavableData(WeaverStateInfo wsi,DataOutputStream s) throws IOException { @@ -259,16 +471,12 @@ public class WeaverStateInfo { } } byte[] data = wsi.unwovenClassFile; - s.writeInt(data.length); - // Do we need to compress the data? - if (!wsi.reweavableCompressedMode) { + + // if we're not in diffMode, write the unwovenClassFile now, + // otherwise we'll insert it as a diff later + if (!wsi.reweavableDiffMode) { + s.writeInt(data.length); s.write(wsi.unwovenClassFile); - } else { - ZipOutputStream zos = new ZipOutputStream(s); - ZipEntry ze = new ZipEntry("data"); - zos.putNextEntry(ze); - zos.write(wsi.unwovenClassFile,0,wsi.unwovenClassFile.length); - zos.closeEntry(); } } } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java index a6fe494f3..05dc3fd14 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java @@ -120,7 +120,6 @@ class BcelClassWeaver implements IClassWeaver { // Static setting across BcelClassWeavers private static boolean inReweavableMode = false; - private static boolean compressReweavableAttributes = false; private List addedSuperInitializersAsList = null; // List<IfaceInitList> @@ -425,17 +424,17 @@ class BcelClassWeaver implements IClassWeaver { // finally, if we changed, we add in the introduced methods. if (isChanged) { - clazz.getOrCreateWeaverStateInfo(); + clazz.getOrCreateWeaverStateInfo(inReweavableMode); weaveInAddedMethods(); // FIXME asc are these potentially affected by declare annotation? } - if (inReweavableMode || clazz.getType().isAspect()) { - WeaverStateInfo wsi = clazz.getOrCreateWeaverStateInfo(); + if (inReweavableMode) { + WeaverStateInfo wsi = clazz.getOrCreateWeaverStateInfo(true); wsi.addAspectsAffectingType(aspectsAffectingType); wsi.setUnwovenClassFileData(ty.getJavaClass().getBytes()); - wsi.setReweavable(true,compressReweavableAttributes); + wsi.setReweavable(true); } else { - clazz.getOrCreateWeaverStateInfo().setReweavable(false,false); + clazz.getOrCreateWeaverStateInfo(false).setReweavable(false); } return isChanged; @@ -926,7 +925,9 @@ class BcelClassWeaver implements IClassWeaver { ShadowMunger aMunger = (ShadowMunger) iter2.next(); if (aMunger instanceof BcelAdvice) { BcelAdvice bAdvice = (BcelAdvice)aMunger; - aspectsAffectingType.add(bAdvice.getConcreteAspect().getName()); + if(bAdvice.getConcreteAspect() != null){ + aspectsAffectingType.add(bAdvice.getConcreteAspect().getName()); + } } else { // It is a 'Checker' - we don't need to remember aspects that only contributed Checkers... } @@ -1769,7 +1770,8 @@ class BcelClassWeaver implements IClassWeaver { shadow.implement(); CompilationAndWeavingContext.leavingPhase(tok); } - mg.matchedShadows = null; + int ii = mg.getMaxLocals(); + mg.matchedShadows = null; } // ---- @@ -1787,9 +1789,12 @@ class BcelClassWeaver implements IClassWeaver { } // Called by the BcelWeaver to let us know all BcelClassWeavers need to collect reweavable info - public static void setReweavableMode(boolean mode,boolean compress) { + public static void setReweavableMode(boolean mode) { inReweavableMode = mode; - compressReweavableAttributes = compress; + } + + public static boolean getReweavableMode() { + return inReweavableMode; } } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index 19cfd39a1..0205d0a08 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -103,7 +103,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { if (changed && munger.changesPublicSignature()) { WeaverStateInfo info = - weaver.getLazyClassGen().getOrCreateWeaverStateInfo(); + weaver.getLazyClassGen().getOrCreateWeaverStateInfo(weaver.getReweavableMode()); info.addConcreteMunger(this); } // Whilst type mungers aren't persisting their source locations, we add this relationship during diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index 275094c88..ae688a5ff 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -1179,7 +1179,10 @@ public class BcelWeaver implements IWeaver { } } } - classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData())); + // old: + //classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData())); + // new: reweavable default with clever diff + classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes()))); } else { classType.resetState(); } @@ -1219,7 +1222,7 @@ public class BcelWeaver implements IWeaver { public UnwovenClassFile[] getClassFilesFor(LazyClassGen clazz) { List childClasses = clazz.getChildClasses(world); UnwovenClassFile[] ret = new UnwovenClassFile[1 + childClasses.size()]; - ret[0] = new UnwovenClassFile(clazz.getFileName(),clazz.getJavaClass(world).getBytes()); + ret[0] = new UnwovenClassFile(clazz.getFileName(),clazz.getJavaClassBytesIncludingReweavable(world)); int index = 1; for (Iterator iter = childClasses.iterator(); iter.hasNext();) { UnwovenClassFile.ChildClass element = (UnwovenClassFile.ChildClass) iter.next(); @@ -1552,10 +1555,10 @@ public class BcelWeaver implements IWeaver { this.progressPerClassFile = progressPerClassFile; } - public void setReweavableMode(boolean mode,boolean compress) { - inReweavableMode = mode; - WeaverStateInfo.setReweavableModeDefaults(mode,compress); - BcelClassWeaver.setReweavableMode(mode,compress); + public void setReweavableMode(boolean xNotReweavable) { + inReweavableMode = !xNotReweavable; + WeaverStateInfo.setReweavableModeDefaults(!xNotReweavable,false,true); + BcelClassWeaver.setReweavableMode(!xNotReweavable); } public boolean isReweavable() { diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java index ccba01c09..04c88df8e 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java @@ -600,6 +600,18 @@ public final class LazyClassGen { writeBack(world); return myGen.getJavaClass(); } + + public byte [] getJavaClassBytesIncludingReweavable(BcelWorld world){ + writeBack(world); + byte [] wovenClassFileData = myGen.getJavaClass().getBytes(); + WeaverStateInfo wsi = myType.getWeaverState();//getOrCreateWeaverStateInfo(); + if(wsi != null && wsi.isReweavable()){ // && !reweavableDataInserted + //reweavableDataInserted = true; + return wsi.replaceKeyWithDiff(wovenClassFileData); + } else{ + return wovenClassFileData; + } + } public void addGeneratedInner(LazyClassGen newClass) { classGens.add(newClass); @@ -749,7 +761,7 @@ public final class LazyClassGen { } public boolean isReweavable() { - if (myType.getWeaverState()==null) return false; + if (myType.getWeaverState()==null) return true; return myType.getWeaverState().isReweavable(); } @@ -757,12 +769,11 @@ public final class LazyClassGen { if (myType.getWeaverState()==null) return null; return myType.getWeaverState().getAspectsAffectingType(); } - - public WeaverStateInfo getOrCreateWeaverStateInfo() { + + public WeaverStateInfo getOrCreateWeaverStateInfo(boolean inReweavableMode) { WeaverStateInfo ret = myType.getWeaverState(); if (ret != null) return ret; - - ret = new WeaverStateInfo(); + ret = new WeaverStateInfo(inReweavableMode); myType.setWeaverState(ret); return ret; } diff --git a/weaver/src/org/aspectj/weaver/weaver-messages.properties b/weaver/src/org/aspectj/weaver/weaver-messages.properties index 533a4374f..9290f3534 100644 --- a/weaver/src/org/aspectj/weaver/weaver-messages.properties +++ b/weaver/src/org/aspectj/weaver/weaver-messages.properties @@ -67,7 +67,7 @@ missingPerClause=expected per clause on super aspect not found on {0} wrongPerClause=wrong kind of per clause on super, expected {0} but found {1} # Reweavable messages... -alreadyWoven=class ''{0}'' is already woven and has not been built with -Xreweavable +alreadyWoven=class ''{0}'' is already woven and has not been built in reweavable mode reweavableMode=weaver operating in reweavable mode. Need to verify any required types exist. processingReweavable=processing reweavable type {0}: {1} missingReweavableType=type {0} is needed by reweavable type {1} |