Hi, Kaffe!!

I have following error when compile jakarta-log4j by ant-1.3 with Kaffe.

--------------
BUILD FAILED

java.lang.OutOfMemoryError
        at java.lang.StringBuffer.ensureCapacity(StringBuffer.java:162)
        at java.lang.StringBuffer.setLength(StringBuffer.java:264)
        at 
org.apache.tools.ant.util.SourceFileScanner.restrict(SourceFileScanner.java:128)
        at 
org.apache.tools.ant.util.SourceFileScanner.restrictAsFiles(SourceFileScanner.java:174)
        at org.apache.tools.ant.taskdefs.Javac.scanDir(Javac.java:488)
        at org.apache.tools.ant.taskdefs.Javac.execute(Javac.java:434)
        at org.apache.tools.ant.Target.execute(Target.java:153)
        at org.apache.tools.ant.Project.runTarget(Project.java:902)
        at org.apache.tools.ant.Project.executeTarget(Project.java:540)
        at org.apache.tools.ant.Project.executeTargets(Project.java:514)
        at org.apache.tools.ant.Main.runBuild(Main.java:421)
        at org.apache.tools.ant.Main.main(Main.java:149)

Total time: 27 seconds
--------------

I looked for the cause.  Maybe following code has problem.

[libraries/javalib/java/lang/StringBuffer.java]

----

// This method assumes synchronization
private boolean ensureCapacity(int minCapacity, boolean forceNew) {

        // Do we really need to create a new buffer?
        if (!forceNew && minCapacity <= buffer.length) {
                return false; 
        }

        // Increase buffer size in powers of two to avoid O(n^2) behavior
        if (minCapacity < used) {
                minCapacity = used;
        } else if (minCapacity < buffer.length * 2 + 2) {
                minCapacity = buffer.length * 2 + 2;
        }

        // Allocate a new buffer and copy data over
        char[] newBuffer = new char[minCapacity];
        System.arraycopy(buffer, 0, newBuffer, 0, used);
        buffer = newBuffer;
        isStringized = false;
        return true;
}
        .
     --snip--   
        .

public synchronized void setLength(int newLength) {
        if (newLength < 0) {
                throw new StringIndexOutOfBoundsException();
        }
        boolean newBuf = ensureCapacity(newLength,
            isStringized || newLength < buffer.length / 2);
        if (!newBuf && newLength > used) {
                for (int index = used; index < newLength; index++)
                        buffer[index] = '\0';
        }
        used = newLength;
}

----

Second argument of ensureCapacity() shows flag to create new buffer.
I suspect following code:

        boolean newBuf = ensureCapacity(newLength,
            isStringized || newLength < buffer.length / 2);

New buffer should be created when StringBuffer has real string already
(isStringized is true) and new buffer length (newLength) is larger
than obsoleted buffer length (buffer.length). 

So, I suggest following code (java.lang.StringBuffer.java):

        boolean newBuf = ensureCapacity(newLength,
            isStringized && ( newLength > buffer.length ));

I can't say certainly, but above code works fine with Ant.
Could you fix it?

regards.
-----------------
Takashi Okamoto

Reply via email to