Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 144420 Details for
Bug 278496
[plan][memory] Out of memory error when weaving
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Patch for asm module
asmpatch.txt (text/plain), 20.84 KB, created by
Andrew Clement
on 2009-08-13 11:40:44 EDT
(
hide
)
Description:
Patch for asm module
Filename:
MIME Type:
Creator:
Andrew Clement
Created:
2009-08-13 11:40:44 EDT
Size:
20.84 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P asm >Index: src/org/aspectj/asm/AsmManager.java >=================================================================== >RCS file: /cvsroot/tools/org.aspectj/modules/asm/src/org/aspectj/asm/AsmManager.java,v >retrieving revision 1.46 >diff -u -r1.46 AsmManager.java >--- src/org/aspectj/asm/AsmManager.java 7 Apr 2009 01:31:04 -0000 1.46 >+++ src/org/aspectj/asm/AsmManager.java 13 Aug 2009 15:42:13 -0000 >@@ -83,9 +83,11 @@ > // below to the AjState for a compilation and recover it if switching > // between projects. > protected IHierarchy hierarchy; >- >- /* Map from String > String - it maps absolute paths for >- * inpath dirs/jars to workspace relative paths suitable for handle inclusion */ >+ >+ /* >+ * Map from String > String - it maps absolute paths for inpath dirs/jars to workspace relative paths suitable for handle >+ * inclusion >+ */ > protected Map inpathMap; > private IRelationshipMap mapper; > private IElementHandleProvider handleProvider; >@@ -654,16 +656,16 @@ > > } > >- private String getTypeNameFromHandle(String handle,Map cache) { >- String typename = (String)cache.get(handle); >- if (typename!=null) { >+ private String getTypeNameFromHandle(String handle, Map cache) { >+ String typename = (String) cache.get(handle); >+ if (typename != null) { > return typename; > } > // inpath handle - but for which type? > // let's do it the slow way, we can optimize this with a cache perhaps > int hasPackage = handle.indexOf('<'); >- int typeLocation = handle.indexOf('['); >- if (typeLocation==-1) { >+ int typeLocation = handle.indexOf('['); >+ if (typeLocation == -1) { > typeLocation = handle.indexOf('}'); > } > if (typeLocation == -1) { >@@ -671,15 +673,16 @@ > return ""; > } > StringBuffer qualifiedTypeNameFromHandle = new StringBuffer(); >- if (hasPackage!=-1) { >- qualifiedTypeNameFromHandle.append(handle.substring(hasPackage+1,handle.indexOf('(',hasPackage))); >+ if (hasPackage != -1) { >+ qualifiedTypeNameFromHandle.append(handle.substring(hasPackage + 1, handle.indexOf('(', hasPackage))); > qualifiedTypeNameFromHandle.append('.'); > } >- qualifiedTypeNameFromHandle.append(handle.substring(typeLocation+1)); >+ qualifiedTypeNameFromHandle.append(handle.substring(typeLocation + 1)); > typename = qualifiedTypeNameFromHandle.toString(); >- cache.put(handle,typename); >+ cache.put(handle, typename); > return typename; > } >+ > /** > * two kinds of relationships > * >@@ -726,7 +729,7 @@ > if (isPhantomHandle(hid)) { > // inpath handle - but for which type? > // TODO promote cache for reuse during one whole model update >- if (!getTypeNameFromHandle(hid,handleToTypenameCache).equals(typename)) { >+ if (!getTypeNameFromHandle(hid, handleToTypenameCache).equals(typename)) { > continue; > } > } >@@ -805,7 +808,7 @@ > // they need removing > for (Iterator targetsIter = targets.iterator(); targetsIter.hasNext();) { > String targethid = (String) targetsIter.next(); >- if (isPhantomHandle(hid) && !getTypeNameFromHandle(hid,handleToTypenameCache).equals(typename)) { >+ if (isPhantomHandle(hid) && !getTypeNameFromHandle(hid, handleToTypenameCache).equals(typename)) { > continue; > } > // Does this point to the same type? >@@ -910,13 +913,13 @@ > } > return (type.equals(containingType)); > } >- >+ > /** > * @param handle a JDT like handle, following the form described in AsmRelationshipProvider.findOrFakeUpNode > * @return true if the handle contains ';' - the char indicating that it is a phantom handle > */ > private boolean isPhantomHandle(String handle) { >- return handle.indexOf(HandleProviderDelimiter.PHANTOM.getDelimiter())!=-1; >+ return handle.indexOf(HandleProviderDelimiter.PHANTOM.getDelimiter()) != -1; > } > > /** >@@ -1307,7 +1310,208 @@ > } > > public String getHandleElementForInpath(String binaryPath) { >- return (String)inpathMap.get(new File(binaryPath)); >+ return (String) inpathMap.get(new File(binaryPath)); >+ } >+ >+ private List pieces = new ArrayList(); >+ >+ private Object intern(String substring) { >+ int lastIdx = -1; >+ if ((lastIdx = substring.lastIndexOf('/')) != -1) { >+ String pkg = substring.substring(0, lastIdx); >+ String type = substring.substring(lastIdx + 1); >+ pkg = internOneThing(pkg); >+ type = internOneThing(type); >+ return new String[] { pkg, type }; >+ } else { >+ return internOneThing(substring); >+ } > } > >+ private String internOneThing(String substring) { >+ // simple name >+ for (int p = 0, max = pieces.size(); p < max; p++) { >+ String s = (String) pieces.get(p); >+ if (s.equals(substring)) { >+ return s; >+ } >+ } >+ pieces.add(substring); >+ return substring; >+ } >+ >+ /** >+ * What we can rely on: <br> >+ * - it is a method signature of the form (La/B;Lc/D;)LFoo;<br> >+ * - there are no generics<br> >+ * >+ * What we must allow for: - may use primitive refs (single chars rather than L) >+ */ >+/* >+ public List compress(String s) { >+ int openParen = 0; >+ int closeParen = s.indexOf(')'); >+ int pos = 1; >+ List compressed = new ArrayList(); >+ // do the parens >+ while (pos < closeParen) { >+ char ch = s.charAt(pos); >+ if (ch == 'L') { >+ int idx = s.indexOf(';', pos); >+ compressed.add(intern(s.substring(pos + 1, idx))); >+ pos = idx + 1; >+ } else if (ch == '[') { >+ int x = pos; >+ while (s.charAt(++pos) == '[') >+ ; >+ // now pos will point at something not an array >+ compressed.add(intern(s.substring(x, pos))); // intern the [[[[[[ >+ char ch2 = s.charAt(pos); >+ if (ch2 == 'L') { >+ int idx = s.indexOf(';', pos); >+ compressed.add(intern(s.substring(pos + 1, idx))); >+ pos = idx + 1; >+ } else if (ch2 == 'T') { >+ int idx = s.indexOf(';'); >+ compressed.add(intern(s.substring(pos, idx + 1))); // should be TT; >+ pos = idx + 1; >+ } else { >+ compressed.add(toCharacter(s.charAt(pos))); >+ pos++; >+ } >+ } else { >+ // it is a primitive ref (SVBCZJ) >+ compressed.add(toCharacter(ch)); >+ pos++; >+ } >+ } >+ // do the return type >+ pos++; >+ char ch = s.charAt(pos); >+ if (ch == 'L') { >+ int idx = s.indexOf(';', pos); >+ compressed.add(intern(s.substring(pos, idx))); >+ } else if (ch == '[') { >+ int x = pos; >+ while (s.charAt(++pos) == '[') >+ ; >+ // now pos will point at something not an array >+ compressed.add(intern(s.substring(x, pos))); // intern the [[[[[[ >+ char ch2 = s.charAt(pos); >+ if (ch2 == 'L') { >+ int idx = s.indexOf(';', pos); >+ compressed.add(intern(s.substring(pos + 1, idx))); >+ pos = idx + 1; >+ } else if (ch2 == 'T') { >+ int idx = s.indexOf(';'); >+ compressed.add(intern(s.substring(pos, idx + 1))); // should be TT; >+ pos = idx + 2; >+ } else { >+ compressed.add(toCharacter(s.charAt(pos))); >+ pos++; >+ } >+ } else { >+ // it is a primitive ref (SVBCZJ) >+ compressed.add(new Character(ch)); >+ } >+ return compressed; >+ >+ // char delimiter = '/'; >+ // int pos = -1; >+ // List compressed = new ArrayList(); >+ // int start = 0; >+ // while ((pos = s.indexOf(delimiter, start)) != -1) { >+ // String part = s.substring(start, pos); >+ // int alreadyRecorded = pieces.indexOf(part); >+ // if (alreadyRecorded != -1) { >+ // compressed.add(new Integer(alreadyRecorded)); >+ // } else { >+ // compressed.add(new Integer(pieces.size())); >+ // pieces.add(part); >+ // } >+ // start = pos + 1; >+ // } >+ // // last piece >+ // String part = s.substring(start, s.length()); >+ // int alreadyRecorded = pieces.indexOf(part); >+ // if (alreadyRecorded != -1) { >+ // compressed.add(youkirtyounew Integer(alreadyRecorded)); >+ // } else { >+ // compressed.add(new Integer(pieces.size())); >+ // pieces.add(part); >+ // } >+ // return compressed; >+ } >+ >+ static final Character charB = new Character('B'); >+ static final Character charS = new Character('S'); >+ static final Character charI = new Character('I'); >+ static final Character charF = new Character('F'); >+ static final Character charD = new Character('D'); >+ static final Character charJ = new Character('J'); >+ static final Character charC = new Character('C'); >+ static final Character charV = new Character('V'); >+ static final Character charZ = new Character('Z'); >+ >+ private Character toCharacter(char ch) { >+ switch (ch) { >+ case 'B': >+ return charB; >+ case 'S': >+ return charS; >+ case 'I': >+ return charI; >+ case 'F': >+ return charF; >+ case 'D': >+ return charD; >+ case 'J': >+ return charJ; >+ case 'C': >+ return charC; >+ case 'V': >+ return charV; >+ case 'Z': >+ return charZ; >+ default: >+ throw new IllegalStateException(new Character(ch).toString()); >+ } >+ } >+ >+ public String decompress(List refs, char delimiter) { >+ StringBuilder result = new StringBuilder(); >+ result.append("("); >+ for (int i = 0, max = refs.size() - 1; i < max; i++) { >+ result.append(unintern(refs.get(i))); >+ } >+ result.append(")"); >+ result.append(unintern(refs.get(refs.size() - 1))); >+ return result.toString(); >+ } >+ >+ private String unintern(Object o) { >+ if (o instanceof Character) { >+ return ((Character) o).toString(); >+ } else if (o instanceof String[]) { >+ String[] strings = (String[]) o; >+ StringBuilder sb = new StringBuilder(); >+ sb.append('L'); >+ sb.append(strings[0]).append('/').append(strings[1]); >+ sb.append(';'); >+ return sb.toString(); >+ } else { // String >+ String so = (String) o; >+ if (so.endsWith(";")) { >+ // will be TT; >+ return so; >+ } else { >+ StringBuilder sb = new StringBuilder(); >+ sb.append('L'); >+ sb.append(so); >+ sb.append(';'); >+ return sb.toString(); >+ } >+ } >+ } >+ */ > } >Index: src/org/aspectj/asm/internal/ProgramElement.java >=================================================================== >RCS file: /cvsroot/tools/org.aspectj/modules/asm/src/org/aspectj/asm/internal/ProgramElement.java,v >retrieving revision 1.47 >diff -u -r1.47 ProgramElement.java >--- src/org/aspectj/asm/internal/ProgramElement.java 11 Jun 2009 22:53:41 -0000 1.47 >+++ src/org/aspectj/asm/internal/ProgramElement.java 13 Aug 2009 15:42:13 -0000 >@@ -305,12 +305,6 @@ > return s; > } > >- public String getBytecodeSignature() { >- String s = (String) kvpairs.get("bytecodeSignature"); >- // if (s==null) return UNDEFINED; >- return s; >- } >- > public void setBytecodeName(String s) { > if (kvpairs == Collections.EMPTY_MAP) > kvpairs = new HashMap(); >@@ -318,9 +312,36 @@ > } > > public void setBytecodeSignature(String s) { >- if (kvpairs == Collections.EMPTY_MAP) >- kvpairs = new HashMap(); >+ initMap(); >+ // Different kinds of format here. The one worth compressing starts with a '(': >+ // (La/b/c/D;Le/f/g/G;)Ljava/lang/String; >+ // maybe want to avoid generics initially. >+ // boolean worthCompressing = s.charAt(0) == '(' && s.indexOf('<') == -1 && s.indexOf('P') == -1; // starts parentheses and >+ // no >+ // // generics >+ // if (worthCompressing) { >+ // kvpairs.put("bytecodeSignatureCompressed", asm.compress(s)); >+ // } else { > kvpairs.put("bytecodeSignature", s); >+ // } >+ } >+ >+ public String getBytecodeSignature() { >+ String s = (String) kvpairs.get("bytecodeSignature"); >+ // if (s == null) { >+ // List compressed = (List) kvpairs.get("bytecodeSignatureCompressed"); >+ // if (compressed != null) { >+ // return asm.decompress(compressed, '/'); >+ // } >+ // } >+ // if (s==null) return UNDEFINED; >+ return s; >+ } >+ >+ private void initMap() { >+ if (kvpairs == Collections.EMPTY_MAP) { >+ kvpairs = new HashMap(); >+ } > } > > public String getSourceSignature() { >@@ -549,22 +570,24 @@ > } > > public String getHandleIdentifier(boolean create) { >+ String h = null; > if (null == handle && create) { > if (asm == null && name.equals("<build to view structure>")) { >- handle = "<build to view structure>"; >+ h = "<build to view structure>"; > } else { > try { >- handle = asm.getHandleProvider().createHandleIdentifier(this); >+ h = asm.getHandleProvider().createHandleIdentifier(this); > } catch (ArrayIndexOutOfBoundsException aioobe) { > throw new RuntimeException("AIOOBE whilst building handle for " + this, aioobe); > } > } > } >- return handle; >+ setHandleIdentifier(h); >+ return h; > } > > public void setHandleIdentifier(String handle) { >- this.handle = handle; >+ // this.handle = handle; > } > > public List getParameterNames() { >Index: src/org/aspectj/asm/internal/JDTLikeHandleProvider.java >=================================================================== >RCS file: /cvsroot/tools/org.aspectj/modules/asm/src/org/aspectj/asm/internal/JDTLikeHandleProvider.java,v >retrieving revision 1.25 >diff -u -r1.25 JDTLikeHandleProvider.java >--- src/org/aspectj/asm/internal/JDTLikeHandleProvider.java 27 Jul 2009 17:27:25 -0000 1.25 >+++ src/org/aspectj/asm/internal/JDTLikeHandleProvider.java 13 Aug 2009 15:42:13 -0000 >@@ -31,10 +31,6 @@ > > private final AsmManager asm; > >- // Need to keep our own count of the number of initializers >- // because this information cannot be gained from the ipe. >- private int initializerCounter = 0; >- > private static final char[] empty = new char[] {}; > private static final char[] countDelim = new char[] { HandleProviderDelimiter.COUNT.getDelimiter() }; > >@@ -46,7 +42,6 @@ > } > > public String createHandleIdentifier(IProgramElement ipe) { >- > // AjBuildManager.setupModel --> top of the tree is either > // <root> or the .lst file > if (ipe == null || (ipe.getKind().equals(IProgramElement.Kind.FILE_JAVA) && ipe.getName().equals("<root>"))) { >@@ -284,7 +279,74 @@ > return CharOperation.concat(countDelim, new Integer(count).toString().toCharArray()); > } > } else if (ipe.getKind().equals(IProgramElement.Kind.INITIALIZER)) { >- return String.valueOf(++initializerCounter).toCharArray(); >+ // return String.valueOf(++initializerCounter).toCharArray(); >+ // Look at any peer advice >+ int count = 1; >+ List kids = ipe.getParent().getChildren(); >+ String ipeSig = ipe.getBytecodeSignature(); >+ // remove return type from the signature - it should not be included in the comparison >+ int idx = 0; >+ if (ipeSig != null && ((idx = ipeSig.indexOf(")")) != -1)) { >+ ipeSig = ipeSig.substring(0, idx); >+ } >+ if (ipeSig != null) { >+ if (ipeSig.indexOf("Lorg/aspectj/lang") != -1) { >+ if (ipeSig.endsWith("Lorg/aspectj/lang/JoinPoint$StaticPart;")) { >+ ipeSig = ipeSig.substring(0, ipeSig.lastIndexOf("Lorg/aspectj/lang/JoinPoint$StaticPart;")); >+ } >+ if (ipeSig.endsWith("Lorg/aspectj/lang/JoinPoint;")) { >+ ipeSig = ipeSig.substring(0, ipeSig.lastIndexOf("Lorg/aspectj/lang/JoinPoint;")); >+ } >+ if (ipeSig.endsWith("Lorg/aspectj/lang/JoinPoint$StaticPart;")) { >+ ipeSig = ipeSig.substring(0, ipeSig.lastIndexOf("Lorg/aspectj/lang/JoinPoint$StaticPart;")); >+ } >+ } >+ } >+ for (Iterator iterator = kids.iterator(); iterator.hasNext();) { >+ IProgramElement object = (IProgramElement) iterator.next(); >+ if (object.equals(ipe)) { >+ break; >+ } >+ if (object.getKind() == ipe.getKind()) { >+ if (object.getName().equals(ipe.getName())) { >+ String sig1 = object.getBytecodeSignature(); >+ if (sig1 != null && (idx = sig1.indexOf(")")) != -1) { >+ sig1 = sig1.substring(0, idx); >+ } >+ // this code needs a speed overhaul... and some proper tests >+ // Two static parts because one may be enclosing jpsp (269522) >+ if (sig1 != null) { >+ if (sig1.indexOf("Lorg/aspectj/lang") != -1) { >+ if (sig1.endsWith("Lorg/aspectj/lang/JoinPoint$StaticPart;")) { >+ sig1 = sig1.substring(0, sig1.lastIndexOf("Lorg/aspectj/lang/JoinPoint$StaticPart;")); >+ } >+ if (sig1.endsWith("Lorg/aspectj/lang/JoinPoint;")) { >+ sig1 = sig1.substring(0, sig1.lastIndexOf("Lorg/aspectj/lang/JoinPoint;")); >+ } >+ if (sig1.endsWith("Lorg/aspectj/lang/JoinPoint$StaticPart;")) { >+ sig1 = sig1.substring(0, sig1.lastIndexOf("Lorg/aspectj/lang/JoinPoint$StaticPart;")); >+ } >+ } >+ } >+ >+ if (sig1 == null && ipeSig == null || (sig1 != null && sig1.equals(ipeSig))) { >+ String existingHandle = object.getHandleIdentifier(); >+ int suffixPosition = existingHandle.indexOf('!'); >+ if (suffixPosition != -1) { >+ count = new Integer(existingHandle.substring(suffixPosition + 1)).intValue() + 1; >+ } else { >+ if (count == 1) { >+ count = 2; >+ } >+ } >+ } >+ } >+ } >+ } >+ // if (count > 1) { >+ return new Integer(count).toString().toCharArray(); >+ // return CharOperation.concat(countDelim, new Integer(count).toString().toCharArray()); >+ // } > } else if (ipe.getKind().equals(IProgramElement.Kind.CODE)) { > int index = CharOperation.lastIndexOf('!', byteCodeName); > if (index != -1) { >@@ -421,6 +483,6 @@ > public void initialize() { > // reset the initializer count. This ensures we return the > // same handle as JDT for initializers. >- initializerCounter = 0; >+ // initializerCounter = 0; > } > } >Index: src/org/aspectj/asm/internal/CharOperation.java >=================================================================== >RCS file: /cvsroot/tools/org.aspectj/modules/asm/src/org/aspectj/asm/internal/CharOperation.java,v >retrieving revision 1.3 >diff -u -r1.3 CharOperation.java >--- src/org/aspectj/asm/internal/CharOperation.java 4 Sep 2008 19:08:10 -0000 1.3 >+++ src/org/aspectj/asm/internal/CharOperation.java 13 Aug 2009 15:42:13 -0000 >@@ -16,6 +16,10 @@ > */ > public class CharOperation { > >+ public static final char[][] NO_CHAR_CHAR = new char[0][]; >+ >+ public static final char[] NO_CHAR = new char[0]; >+ > /** > * Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation > */ >@@ -34,6 +38,44 @@ > return result; > } > >+ public static final char[][] subarray(char[][] array, int start, int end) { >+ if (end == -1) >+ end = array.length; >+ if (start > end) >+ return null; >+ if (start < 0) >+ return null; >+ if (end > array.length) >+ return null; >+ >+ char[][] result = new char[end - start][]; >+ System.arraycopy(array, start, result, 0, end - start); >+ return result; >+ } >+ >+ public static final char[][] splitOn(char divider, char[] array) { >+ int length = array == null ? 0 : array.length; >+ if (length == 0) >+ return NO_CHAR_CHAR; >+ >+ int wordCount = 1; >+ for (int i = 0; i < length; i++) >+ if (array[i] == divider) >+ wordCount++; >+ char[][] split = new char[wordCount][]; >+ int last = 0, currentWord = 0; >+ for (int i = 0; i < length; i++) { >+ if (array[i] == divider) { >+ split[currentWord] = new char[i - last]; >+ System.arraycopy(array, last, split[currentWord++], 0, i - last); >+ last = i + 1; >+ } >+ } >+ split[currentWord] = new char[length - last]; >+ System.arraycopy(array, last, split[currentWord], 0, length - last); >+ return split; >+ } >+ > /** > * Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation > */ >@@ -88,6 +130,67 @@ > return true; > } > >+ final static public String toString(char[][] array) { >+ char[] result = concatWith(array, '.'); >+ return new String(result); >+ } >+ >+ public static final char[] concatWith(char[][] array, char separator) { >+ int length = array == null ? 0 : array.length; >+ if (length == 0) >+ return CharOperation.NO_CHAR; >+ >+ int size = length - 1; >+ int index = length; >+ while (--index >= 0) { >+ if (array[index].length == 0) >+ size--; >+ else >+ size += array[index].length; >+ } >+ if (size <= 0) >+ return CharOperation.NO_CHAR; >+ char[] result = new char[size]; >+ index = length; >+ while (--index >= 0) { >+ length = array[index].length; >+ if (length > 0) { >+ System.arraycopy(array[index], 0, result, (size -= length), length); >+ if (--size >= 0) >+ result[size] = separator; >+ } >+ } >+ return result; >+ } >+ >+ public static final int hashCode(char[] array) { >+ int length = array.length; >+ int hash = length == 0 ? 31 : array[0]; >+ if (length < 8) { >+ for (int i = length; --i > 0;) >+ hash = (hash * 31) + array[i]; >+ } else { >+ // 8 characters is enough to compute a decent hash code, don't waste time examining every character >+ for (int i = length - 1, last = i > 16 ? i - 16 : 0; i > last; i -= 2) >+ hash = (hash * 31) + array[i]; >+ } >+ return hash & 0x7FFFFFFF; >+ } >+ >+ public static final boolean equals(char[][] first, char[][] second) { >+ if (first == second) >+ return true; >+ if (first == null || second == null) >+ return false; >+ if (first.length != second.length) >+ return false; >+ >+ for (int i = first.length; --i >= 0;) >+ if (!equals(first[i], second[i])) >+ return false; >+ return true; >+ } >+ > /** > * Taken from org.aspectj.org.eclipse.jdt.core.compiler.CharOperation > */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 278496
:
137761
|
138340
|
138342
|
138347
|
138813
|
138982
|
138984
|
138985
|
138986
|
138987
|
139581
|
139885
|
139886
|
139924
|
139925
|
139926
|
140051
|
140052
|
140053
|
140273
|
143923
| 144420 |
144756
|
174893
|
177807