Re: [cp-patches] [PATCH] Fix raw type references in AnnotationInvocationHandler

2011-10-12 Thread Ian Rogers
On 12 October 2011 03:52, Mark Wielaard m...@klomp.org wrote:
 On Wed, 2011-10-12 at 10:29 +0300, Pekka Enberg wrote:
 On Wed, Oct 12, 2011 at 1:28 AM, Dr Andrew John Hughes
 ahug...@redhat.com wrote:
  If we're going to change that, it should happen after the next release
  and with plenty of discussion / heads up for VMs.

 Right. I guess I could send patches for JamVM, CACAO, and Jato as
 well. Are there other VMs we care about?

 JikesRVM and GCJ of course!
 Although they only use part of the VM interface at this time.
 There is a somewhat full list at:
 https://www.gnu.org/software/classpath/stories.html#jvm
 Some of those are somewhat in hibernation though.
 Heay, and JATO is missing...

 And if we are going to extend/adapt the VM interface anyway, it would
 not harm to work on the Common Virtual Machine Interface (CVMI) project
 http://icedtea.classpath.org/wiki/CVMIDiscussion
 (Heay, I can dream :)

 Cheers,

 Mark

Jikes RVM is woefully out-of-date wrt Classpath, MRP
(http://mrp.codehaus.org/) isn't :-)

Regards,
Ian



Re: netif.h present but unusable on Mac

2009-11-25 Thread Ian Rogers
Hi Richard,

Jikes RVM is using an older version of Classpath than what is current.
MRP [1] (derived from Jikes RVM) uses the latest GNU Classpath. You
may want to try this as an alternative, although currently you'll need
to download MRP using git.

Regards,
Ian

[1] http://mrp.codehaus.org/

2009/11/22 Richard O'Keefe o...@cs.otago.ac.nz:
 The host is an Intel Core 2 Duo processor running Mac OS X version 10.5.7

 I downloaded the JikesRVM version 3.1.0 and having checked that
 ia32-osx was supported set out to build it.  The manual says that
 it needs GNU Classpath, and that I should download and install
 that by doing ant -f build/components/classpath.xml, which I did.

     [exec] checking ifaddrs.h usability... yes
     [exec] checking ifaddrs.h presence... yes
     [exec] checking for ifaddrs.h... yes
     [exec] checking netinet/in_systm.h usability... yes
     [exec] checking netinet/in_systm.h presence... yes
     [exec] checking for netinet/in_systm.h... yes
     [exec] checking netinet/ip.h usability... yes
     [exec] checking netinet/ip.h presence... yes
     [exec] checking for netinet/ip.h... yes
     [exec] checking net/if.h usability... no
     [exec] checking net/if.h presence... yes
     [exec] configure: WARNING: net/if.h: present but cannot be compiled
     [exec] configure: WARNING: net/if.h:     check for missing prerequisite
 headers?
     [exec] configure: WARNING: net/if.h: see the Autoconf documentation
     [exec] configure: WARNING: net/if.h:     section Present But Cannot Be
 Compiled
     [exec] configure: WARNING: net/if.h: proceeding with the preprocessor's
 result
     [exec] configure: WARNING: net/if.h: in the future, the compiler will
 take precedence
     [exec] configure: WARNING:     ##  ##
     [exec] configure: WARNING:     ## Report this to classpath@gnu.org ##
     [exec] configure: WARNING:     ##  ##
     [exec] checking for net/if.h... yes

 There was a further problem later down where the Ant script said
     [exec] configure: error: The Java compiler
 /home/cshome/o/ok/Desktop/jikesrvm-3.1.0/components/ecj/3.2/ecj-3.2/ecj
 failed (see config.log, check the CLASSPATH?)
     [exec] checking if
 /home/cshome/o/ok/Desktop/jikesrvm-3.1.0/components/ecj/3.2/ecj-3.2/ecj
 works...


 Since ...components/ecj doesn't exist, it's not surprising that it
 doesn't work.  This leads me to suspect a problem with the Ant
 script.






Re: [cp-patches] FYI: Add VM updates in 0.98

2009-02-09 Thread Ian Rogers
Hi,

I've attached a revision for the reflection classes that is applied to
Jikes RVM and has been updated for 0.98. This patch removes the messy
backlink mechanism in reflection and better supports eliminating
reflection overhead in Jikes RVM. Due to the problems it would cause
to VMs thought is needed before applying the patch.

Regards,
Ian

2009/2/9 Nicolas Geoffray nicolas.geoff...@menlina.com:
 Hi Andrew,

 Andrew John Hughes wrote:

 This updates NEWS with the VM updates in 0.98.

 2009-02-05  Andrew John Hughes  ahug...@redhat.com

* NEWS: Add VM updates.


 So I guess it's too late now, but forgot to talk about VMField, VMMethod and
 VMConstructor which I think are new in 0.98.

 Cheers,
 Nicolas



Index: java/lang/reflect/Constructor.java
===
RCS file: /sources/classpath/classpath/java/lang/reflect/Constructor.java,v
retrieving revision 1.10
diff -u -r1.10 Constructor.java
--- java/lang/reflect/Constructor.java	23 Jun 2008 20:59:35 -	1.10
+++ java/lang/reflect/Constructor.java	18 Aug 2008 17:14:28 -
@@ -95,7 +95,6 @@
   Constructor(VMConstructor cons)
   {
 this.cons = cons;
-cons.cons = this;
   }
 
   private Constructor()
@@ -316,7 +315,7 @@
   {
 // Inescapable as the VM layer is 1.4 based. 
 @SuppressWarnings(unchecked)
-  T ins = (T) cons.construct(args);
+  T ins = (T) cons.construct(args, this);
 return ins;
   }
 
Index: java/lang/reflect/Field.java
===
RCS file: /sources/classpath/classpath/java/lang/reflect/Field.java,v
retrieving revision 1.10
diff -u -r1.10 Field.java
--- java/lang/reflect/Field.java	23 Jun 2008 20:59:35 -	1.10
+++ java/lang/reflect/Field.java	18 Aug 2008 17:14:28 -
@@ -96,7 +96,6 @@
   Field(VMField f)
   {
 this.f = f;
-f.f = this;
   }
 
   /**
@@ -257,7 +256,7 @@
   public Object get(Object o)
 throws IllegalAccessException
   {
-return f.get(o);
+return f.get(this, o);
   }
 
   /**
@@ -280,7 +279,7 @@
   public boolean getBoolean(Object o)
 throws IllegalAccessException
   {
-return f.getBoolean(o);
+return f.getBoolean(this, o);
   }
 
   /**
@@ -303,7 +302,7 @@
   public byte getByte(Object o)
 throws IllegalAccessException
   {
-return f.getByte(o);
+return f.getByte(this, o);
   }
 
   /**
@@ -324,7 +323,7 @@
   public char getChar(Object o)
 throws IllegalAccessException
   {
-return f.getChar(o);
+return f.getChar(this, o);
   }
 
   /**
@@ -347,7 +346,7 @@
   public short getShort(Object o)
 throws IllegalAccessException
   {
-return f.getShort(o);
+return f.getShort(this, o);
   }
 
   /**
@@ -370,7 +369,7 @@
   public int getInt(Object o)
 throws IllegalAccessException
   {
-return f.getInt(o);
+return f.getInt(this, o);
   }
 
   /**
@@ -393,7 +392,7 @@
   public long getLong(Object o)
 throws IllegalAccessException
   {
-return f.getLong(o);
+return f.getLong(this, o);
   }
 
   /**
@@ -416,7 +415,7 @@
   public float getFloat(Object o)
 throws IllegalAccessException
   {
-return f.getFloat(o);
+return f.getFloat(this, o);
   }
 
   /**
@@ -440,7 +439,7 @@
   public double getDouble(Object o)
 throws IllegalAccessException
   {
-return f.getDouble(o);
+return f.getDouble(this, o);
   }
 
   /**
@@ -491,7 +490,7 @@
   public void set(Object o, Object value)
 throws IllegalAccessException
   {
-f.set(o, value);
+f.set(this, o, value);
   }
 
   /**
@@ -514,7 +513,7 @@
   public void setBoolean(Object o, boolean value)
 throws IllegalAccessException
   {
-f.setBoolean(o, value);
+f.setBoolean(this, o, value);
   }
 
   /**
@@ -537,7 +536,7 @@
   public void setByte(Object o, byte value)
 throws IllegalAccessException
   {
-f.setByte(o, value);
+f.setByte(this, o, value);
   }
 
   /**
@@ -560,7 +559,7 @@
   public void setChar(Object o, char value)
 throws IllegalAccessException
   {
-f.setChar(o, value);
+f.setChar(this, o, value);
   }
 
   /**
@@ -583,7 +582,7 @@
   public void setShort(Object o, short value)
 throws IllegalAccessException
   {
-f.setShort(o, value);
+f.setShort(this, o, value);
   }
 
   /**
@@ -606,7 +605,7 @@
   public void setInt(Object o, int value)
 throws IllegalAccessException
   {
-f.setInt(o, value);
+f.setInt(this, o, value);
   }
 
   /**
@@ -629,7 +628,7 @@
   public void setLong(Object o, long value)
 throws IllegalAccessException
   {
-f.setLong(o, value);
+f.setLong(this, o, value);
   }
 
   /**
@@ -652,7 +651,7 @@
   public void setFloat(Object o, float value)
 throws IllegalAccessException
   {
-f.setFloat(o, value);
+f.setFloat(this, o, value);
   }
 
   /**
@@ -675,7 +674,7 @@
   public void setDouble(Object o, double value)
 throws IllegalAccessException
   {
-f.setDouble(o, value);
+f.setDouble(this, o, value);
  

Problems with Jikes RVM and Ubuntu 8.10

2008-11-06 Thread Ian Rogers

Hi,

has anyone else tried running Classpath on Ubuntu 8.10? When I run 
DaCapo antlr I'm getting a problem that a test of File.exists and then 
File.canWrite (apologies if these aren't the exact method names) is 
failing. I believe the error is the call to exists is giving a false 
positive and then the call to canWrite fails as the file doesn't exist. 
One cause may be that the errno value is 0. This affliction may be Jikes 
RVM specific as we're compiling Classpath with -m32 on Intel 64bit (the 
platform I'm testing). Before digging too deep I thought I'd ask if any 
one else had solved the same problem?


Thanks,
Ian Rogers
--
http://www.cs.man.ac.uk/~irogers/



Jikes RVM 3.0.1 released

2008-10-17 Thread Ian Rogers
Jikes RVM version 3.0.1 has been released and is available for download
at _http://downloads.sourceforge.net/jikesrvm/jikesrvm-3.0.1.tar.bz2_
http://downloads.sourceforge.net/jikesrvm/jikesrvm-3.0.1.tar.bz2  
 
The detailed release notes for major changes since 3.0.0 can be found
below or in JIRA
(_http://jira.codehaus.org/browse/RVM/fixforversion/14378_
http://jira.codehaus.org/browse/RVM/fixforversion/14378). 
 
** New Feature 
* [RVM-507] - Initial prototype of TuningFork trace generation in Jikes RVM 
* [RVM-515] - Make boot image writer traversal of object graph configurable 
* [RVM-517] - Reflection optimization 
* [RVM-528] - Support for eclipse-project with Harmony class libraries 
* [RVM-634] - Add RuntimePure annotation to indicate when a Pure
annotation should only be respected at runtime 
* [RVM-673] - Implement Inline.When.AssertionsDisabled pragma 
 
** Improvement 
* [RVM-291] - Immortal objects with address based hashing should set
their hashed bit during boot image writing 
* [RVM-443] - Avoid back references in java.lang.reflect VMXXX classes 
* [RVM-476] - Make lock allocation thread-model-agnostic. 
* [RVM-627] - Use java.nio for writing boot image 
* [RVM-632] - Space improvements of RVMClass.objectCache 
* [RVM-633] - Avoid the use of Reflection to invoke Object.finalize() 
* [RVM-644] - Reduce copying of char[] in java.lang.reflect.Proxy 
* [RVM-650] - Ask users to submit bug reports on Jikes RVM crashes 
 
** Bug 
* [RVM-172] - Failing DaCapo benchmarks on PPC 32 OS X 
* [RVM-288] - Assertion failure in inline oracle 
* [RVM-318] - java.util.Scanner is unimplemented 
* [RVM-346] - SPECjvm98: Invalid runs should not be SUCCESSes 
* [RVM-410] - Problem with changes to stack walk 
* [RVM-440] - Poisoned tests failing in finalizer thread 
* [RVM-471] - Stack frame alignment broken for Intel on OS/X 
* [RVM-605] - Possible fix for FreeListPageResource.releasePages() 
* [RVM-606] - Problems with OSR guarded inlining of invokeinterface  
* [RVM-614] - BaseBasePoisoned build segfaults during VM bootup on
pcc64-linux 
* [RVM-617] - DaCapo bloat fails with Apache Harmony class library 
* [RVM-619] - DaCapo eclipse fails with Apache Harmony class library 
* [RVM-621] - DaCapo xalan fails with Apache Harmony class library 
* [RVM-623] - Intel 16bit operations with immediate operands in some
cases generate 32bit immediate operands rather than 16bit 
* [RVM-631] - Bug in new Finalization code 
* [RVM-636] - Crash in reflection during JSR-166 TCK 
* [RVM-643] - Invalid InstructionFormat usage in Simplifier, but real
bug is that IR is semantically malformed 
* [RVM-645] - Bug in LiveAnalysis related to modeling of dataflow
through Exception edges in the FCFG 
* [RVM-646] - Immix defrag broken 
* [RVM-652] - build failure on IA32 OS X 10.5 (Leopard) 
 
** Tasks and Sub-task 
* [RVM-651] - Add support to Intel assembler for REX prefix byte 
* [RVM-667] - Modify the implementation of table switch 
* [RVM-669] - Build/boot image runner support for x86 64 
* [RVM-671] - Fix spill location size estimates




Re: [cp-patches] FYI: ThreadLocal optimisation

2008-09-12 Thread Ian Rogers

Andrew Haley wrote:

Andrew John Hughes wrote:
  

Daniel's copyright assignment is finally through, so
I'm committing this patch which optimises the use of
ThreadLocals by replacing the use of the generic java.util.WeakHashMap
with a ThreadLocal-specific implementation.



It's slightly weird to be doing this in pure Java: all POSIX-
compatible systems have thread-local variables, and the glibc
implementation is very fast.  Still, I'm sure this patch is an
improvement.

Andrew.

  

Hi Andrew,

I agree with what you say for static compilation. I think there's room 
for improvement in the pthread interfaces for getting thread locals 
especially if you want to have JIT compiled code that accesses them. For 
example, I use the below to compute a static thread local's offset and 
it is x86 specific:


#include stdio.h
static __thread char *hello;
int main(int argc, char **argv) {
 int offset;
 asm (mov [EMAIL PROTECTED], %0 : =r(offset));
 hello = hello;
 printf(%p %s %d,hello, hello, offset);
}

As the patch comes from Jikes RVM it should be no surprise we addressed 
solving the performance problem in a metacircular manner. I imagine 
DaCapo jython is a lot faster on Classpath runtimes now.



Regards,
Ian



[cp-patches] RFC: Try to reduce char[] copying in jlr.Proxy

2008-08-29 Thread Ian Rogers

Hi,

the attached patch is trying to continue Andrew's good work and reduce 
the amount of redundant array copying, in this case in jlr.Proxy. There 
is a TODO in that we have no back door to turn a char[] in to a String 
without copying.


Thanks,
Ian
Index: java/lang/reflect/Proxy.java
===
RCS file: /sources/classpath/classpath/java/lang/reflect/Proxy.java,v
retrieving revision 1.30
diff -u -r1.30 Proxy.java
--- java/lang/reflect/Proxy.java16 Mar 2008 22:04:51 -  1.30
+++ java/lang/reflect/Proxy.java29 Aug 2008 11:01:45 -
@@ -1402,7 +1402,12 @@
 {
   String utf8 = toUtf8(str);
   int len = utf8.length();
-  return poolIndex(\1 + (char) (len  8) + (char) (len  0xff) + utf8);
+  CPStringBuilder buf = new CPStringBuilder(len+3);
+  buf.append('\1');
+  buf.append((char) (len  8));
+  buf.append((char) (len  0xff));
+  buf.append(utf8);
+  return poolIndex(buf.toString());
 }
 
 /**
@@ -1416,7 +1421,7 @@
 {
   char index = utf8Info(name);
   char[] c = {7, (char) (index  8), (char) (index  0xff)};
-  return poolIndex(new String(c));
+  return poolIndex(stringFromCharArray(c));
 }
 
 /**
@@ -1452,7 +1457,7 @@
   char[] c = {(char) (structure + 8),
   (char) (cindex  8), (char) (cindex  0xff),
   (char) (ntindex  8), (char) (ntindex  0xff)};
-  return poolIndex(new String(c));
+  return poolIndex(stringFromCharArray(c));
 }
 
 /**
@@ -1469,7 +1474,7 @@
   char tindex = utf8Info(type);
   char[] c = {12, (char) (nindex  8), (char) (nindex  0xff),
   (char) (tindex  8), (char) (tindex  0xff)};
-  return poolIndex(new String(c));
+  return poolIndex(stringFromCharArray(c));
 }
 
 /**
@@ -1541,5 +1546,19 @@
 }
   return (char) i.intValue();
 }
+
+/**
+ * Return a String wrapping the char array avoiding copying the char array
+ * if possible
+ *
+ * @param c the char array
+ * @return the String
+ */
+private String stringFromCharArray(char[] c)
+{
+  // TODO: we need some back door like VMCPStringBuilder to avoid copying
+  //   the character array in this situation
+  return new String(c);
+}
   } // class ClassFactory
 }


[cp-patches] State of Jikes RVM patches waiting to go into Classpath

2008-08-18 Thread Ian Rogers

Hi,

currently there are 3 patches waiting to go into GNU Classpath from 
Jikes RVM:


1) Thread Local improvements:
http://jira.codehaus.org/browse/RVM-185
http://jikesrvm.svn.sourceforge.net/viewvc/jikesrvm/rvmroot/trunk/build/components/patches/classpath-cvs.RVM-185.patch?revision=13369view=markup
I believe this is stalled waiting for Daniel's FSF paper work. This 
patch would be a big performance win for many VMs.


2) ZipEntry improvements:
http://jira.codehaus.org/browse/RVM-392
http://jikesrvm.svn.sourceforge.net/viewvc/jikesrvm/rvmroot/trunk/build/components/patches/classpath-cvs.RVM-392.patch?revision=14005view=markup
This patch cleans up the use of Calendar in ZipEntry and avoids 
unnecessary bouncing between UNIX and DOS time formats. Possible 
bootstrap issues were raised by Tom Tromey, so the patch is still 
pending. Here's the e-mail thread:

http://www.nabble.com/RFC%3A-tweaks-to-java.util.zip.ZipEntry-to15289313.html#a15289313

3) AIX build fix:
http://jira.codehaus.org/browse/RVM-526
http://jikesrvm.svn.sourceforge.net/viewvc/jikesrvm/rvmroot/trunk/build/components/patches/classpath-cvs.RVM-526.patch?revision=14551view=markup
This is a small patch that fixes a problem for builds on AIX, I believe 
it would be safe to commit it.


I'd like to push these patches up stream. For 2 and 3 please could 
people complain if they think they are an issue for their VM, I believe 
they are both steps in the right direction. For 1 could someone chase up 
the paper work?


Thanks,
Ian Rogers




[cp-patches] RFC: AIX build fix - paths too long in check_jni.sh

2008-08-18 Thread Ian Rogers
Dave Grove fixed an AIX build issue for the Jikes RVM with the attached 
patch. Jikes RVM tracker here:

http://jira.codehaus.org/browse/RVM-526

Regards,
Ian Rogers
Index: scripts/check_jni_methods.sh.in
===
RCS file: /sources/classpath/classpath/scripts/check_jni_methods.sh.in,v
retrieving revision 1.5
diff -u -r1.5 check_jni_methods.sh.in
--- scripts/check_jni_methods.sh.in 11 Jun 2008 21:37:49 -  1.5
+++ scripts/check_jni_methods.sh.in 23 Jun 2008 20:03:20 -
@@ -6,12 +6,16 @@
 TMPFILE=/tmp/check-jni-methods.$$.1
 TMPFILE2=/tmp/check-jni-methods.$$.2
 TMPFILE3=/tmp/check-jni-methods.$$.3
+TMPFILE4=/tmp/check-jni-methods.$$.4
 
 # Find all methods defined in the header files generated
 # from the java source files.
-grep -h '^JNIEXPORT .* Java_' @abs_top_builddir@/include/*.h 
@abs_top_srcdir@/include/*.h | \
-LC_ALL=C sed -e 's,.*JNICALL \(Java_[a-z_A-Z0-9]*\).*$,\1,' | \
-   sort -u  $TMPFILE
+grep -h '^JNIEXPORT .* Java_' @abs_top_srcdir@/include/*.h | \
+LC_ALL=C sed -e 's,.*JNICALL \(Java_[a-z_A-Z0-9]*\).*$,\1,'  $TMPFILE
+grep -h '^JNIEXPORT .* Java_' @abs_top_builddir@/include/*.h | \
+LC_ALL=C sed -e 's,.*JNICALL \(Java_[a-z_A-Z0-9]*\).*$,\1,'  $TMPFILE
+sort -u $TMPFILE  $TMPFILE4
+mv $TMPFILE4 $TMPFILE
 
 # Find all methods in the JNI C source files.
 find @abs_top_srcdir@/native/jni -name \*.c | \


Re: [cp-patches] [rvm-core] State of Jikes RVM patches waiting to go into Classpath

2008-08-18 Thread Ian Rogers

Andrew John Hughes wrote:

On 18/08/2008, Ian Rogers [EMAIL PROTECTED] wrote:
  

Thanks Andrew,

 Andrew John Hughes wrote:



On 18/08/2008, Ian Rogers [EMAIL PROTECTED] wrote:


  

Hi,

 currently there are 3 patches waiting to go into GNU Classpath from
 Jikes RVM:





Note that 0.98 is very imminent i.e. I'd like it to be released this
week and most of it has already been merged to GCJ.



  

 1) Thread Local improvements:
 http://jira.codehaus.org/browse/RVM-185



http://jikesrvm.svn.sourceforge.net/viewvc/jikesrvm/rvmroot/trunk/build/components/patches/classpath-cvs.RVM-185.patch?revision=13369view=markup


 I believe this is stalled waiting for Daniel's FSF paper work. This
 patch would be a big performance win for many VMs.





The assignment is still pending.  The last e-mail I have is Daniel's
assignment form on 11th June.  I've pinged to see what's going on.


  

 Great! Getting this into 0.98 would be a real feature.




I hope your luck's in then and the assignment has been done... :)

  

 2) ZipEntry improvements:
 http://jira.codehaus.org/browse/RVM-392



http://jikesrvm.svn.sourceforge.net/viewvc/jikesrvm/rvmroot/trunk/build/components/patches/classpath-cvs.RVM-392.patch?revision=14005view=markup


 This patch cleans up the use of Calendar in ZipEntry and avoids
 unnecessary bouncing between UNIX and DOS time formats. Possible
 bootstrap issues were raised by Tom Tromey, so the patch is still
 pending. Here's the e-mail thread:



http://www.nabble.com/RFC%3A-tweaks-to-java.util.zip.ZipEntry-to15289313.html#a15289313





I'm sceptical about committing this one for 0.98 if there may be
issues.  I assume the gain is it not using a synchronized method to
initialise the Calendar?  Have you considered the initialization on
demand holder idiom instead?


  

http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom


It's also mentioned in the JSR166 book by Doug Lea et. al.  I can see
why initialising Calendar as a prerequisite for zip support might
cause a lot of problems and I don't think we have time to test it well
enough for this release.


  

 Sorry, this change is a bit more involved than initialization on demand.
Basically the normal use for a ZipEntry is for reading. In the current code
to read an entry we must also convert the date (that is in DOS form in a
ZIP) into a canonical unix time form, hence the requirement for a Calendar
(and boot strap problems if the Calendar is in the zip). The main point of
the patch is that we only really need the canonical time if we are writing
the ZipEntry or if someone is querying it, in such a circumstance calling
Calendar.getInstance() is fine and any caching can be done there.

 The patch is necessary for Jikes RVM as it avoids a boot strap issue (we
don't need a Calendar to be in the boot image before we start reading a
zip). I *really* don't want Calendars in Jikes RVM's boot image as I have to
hand code conversion code between the different JDK and Classpath formats,
hence initialization on demand is definitely not a solution.

 This patch is a good thing in my opinion and hasn't caused any issues for
Jikes RVM, I would like to see it included in 0.98. It will help other VMs
with the same bootstrap issue.




Your discussion made no sense at first, until I realised you were
linking to your first attempt at a patch. The real one is completely
different:

  
http://www.nabble.com/Re%3A-RFC%3A-tweaks-to-java.util.zip.ZipEntry-p15331002.html

and now your comments make sense... ;) Have you tested with any other VMs?
  


Sorry about that, it's the same thread just at the end rather than the 
initial patch.  What are these other VMs you speak of ;-) Can I apply it 
and see if something somewhere falls over then fix it, rather than 
pre-emptively finding things out about VMs I don't use.



 3) AIX build fix:
 http://jira.codehaus.org/browse/RVM-526



http://jikesrvm.svn.sourceforge.net/viewvc/jikesrvm/rvmroot/trunk/build/components/patches/classpath-cvs.RVM-526.patch?revision=14551view=markup


 This is a small patch that fixes a problem for builds on AIX, I believe
 it would be safe to commit it.





I think I've seen this before.  Seems fine.  Can you forward it for
discussion on cp-patches?


  

 Maybe Dave can, he's assigned the issue to himself.




The patch seems trivial enough, just breaking the process up
presumably due to resource constraints on AIX.  But I don't think it
has been posted to the Classpath list at all so far.
  


Posted.


 Thanks,

 Ian






  





[cp-patches] RFC: Avoid back references in java.lang.reflect VMXXX classes

2008-08-18 Thread Ian Rogers

This patch is part of Jikes RVM JIRA issue 443:

http://jira.codehaus.org/browse/RVM-443

committed here:

http://jikesrvm.svn.sourceforge.net/viewvc/jikesrvm?view=revrevision=14905

The patch avoids back references in java.lang.reflect.VM* classes and 
instead passes the parent object as a parameter. This means that 
constant parents can be propagated rather than in the current code where 
the parent must be loaded from a non-final field (breaking potential 
optimization without pointer analysis).


The patch changes the internal reflection API and therefore would need a 
number of changes in other Classpath VMs to match the interface.


Regards,
Ian
Index: java/lang/reflect/Constructor.java
===
RCS file: /sources/classpath/classpath/java/lang/reflect/Constructor.java,v
retrieving revision 1.10
diff -u -r1.10 Constructor.java
--- java/lang/reflect/Constructor.java  23 Jun 2008 20:59:35 -  1.10
+++ java/lang/reflect/Constructor.java  18 Aug 2008 17:14:28 -
@@ -95,7 +95,6 @@
   Constructor(VMConstructor cons)
   {
 this.cons = cons;
-cons.cons = this;
   }
 
   private Constructor()
@@ -316,7 +315,7 @@
   {
 // Inescapable as the VM layer is 1.4 based. 
 @SuppressWarnings(unchecked)
-  T ins = (T) cons.construct(args);
+  T ins = (T) cons.construct(args, this);
 return ins;
   }
 
Index: java/lang/reflect/Field.java
===
RCS file: /sources/classpath/classpath/java/lang/reflect/Field.java,v
retrieving revision 1.10
diff -u -r1.10 Field.java
--- java/lang/reflect/Field.java23 Jun 2008 20:59:35 -  1.10
+++ java/lang/reflect/Field.java18 Aug 2008 17:14:28 -
@@ -96,7 +96,6 @@
   Field(VMField f)
   {
 this.f = f;
-f.f = this;
   }
 
   /**
@@ -257,7 +256,7 @@
   public Object get(Object o)
 throws IllegalAccessException
   {
-return f.get(o);
+return f.get(this, o);
   }
 
   /**
@@ -280,7 +279,7 @@
   public boolean getBoolean(Object o)
 throws IllegalAccessException
   {
-return f.getBoolean(o);
+return f.getBoolean(this, o);
   }
 
   /**
@@ -303,7 +302,7 @@
   public byte getByte(Object o)
 throws IllegalAccessException
   {
-return f.getByte(o);
+return f.getByte(this, o);
   }
 
   /**
@@ -324,7 +323,7 @@
   public char getChar(Object o)
 throws IllegalAccessException
   {
-return f.getChar(o);
+return f.getChar(this, o);
   }
 
   /**
@@ -347,7 +346,7 @@
   public short getShort(Object o)
 throws IllegalAccessException
   {
-return f.getShort(o);
+return f.getShort(this, o);
   }
 
   /**
@@ -370,7 +369,7 @@
   public int getInt(Object o)
 throws IllegalAccessException
   {
-return f.getInt(o);
+return f.getInt(this, o);
   }
 
   /**
@@ -393,7 +392,7 @@
   public long getLong(Object o)
 throws IllegalAccessException
   {
-return f.getLong(o);
+return f.getLong(this, o);
   }
 
   /**
@@ -416,7 +415,7 @@
   public float getFloat(Object o)
 throws IllegalAccessException
   {
-return f.getFloat(o);
+return f.getFloat(this, o);
   }
 
   /**
@@ -440,7 +439,7 @@
   public double getDouble(Object o)
 throws IllegalAccessException
   {
-return f.getDouble(o);
+return f.getDouble(this, o);
   }
 
   /**
@@ -491,7 +490,7 @@
   public void set(Object o, Object value)
 throws IllegalAccessException
   {
-f.set(o, value);
+f.set(this, o, value);
   }
 
   /**
@@ -514,7 +513,7 @@
   public void setBoolean(Object o, boolean value)
 throws IllegalAccessException
   {
-f.setBoolean(o, value);
+f.setBoolean(this, o, value);
   }
 
   /**
@@ -537,7 +536,7 @@
   public void setByte(Object o, byte value)
 throws IllegalAccessException
   {
-f.setByte(o, value);
+f.setByte(this, o, value);
   }
 
   /**
@@ -560,7 +559,7 @@
   public void setChar(Object o, char value)
 throws IllegalAccessException
   {
-f.setChar(o, value);
+f.setChar(this, o, value);
   }
 
   /**
@@ -583,7 +582,7 @@
   public void setShort(Object o, short value)
 throws IllegalAccessException
   {
-f.setShort(o, value);
+f.setShort(this, o, value);
   }
 
   /**
@@ -606,7 +605,7 @@
   public void setInt(Object o, int value)
 throws IllegalAccessException
   {
-f.setInt(o, value);
+f.setInt(this, o, value);
   }
 
   /**
@@ -629,7 +628,7 @@
   public void setLong(Object o, long value)
 throws IllegalAccessException
   {
-f.setLong(o, value);
+f.setLong(this, o, value);
   }
 
   /**
@@ -652,7 +651,7 @@
   public void setFloat(Object o, float value)
 throws IllegalAccessException
   {
-f.setFloat(o, value);
+f.setFloat(this, o, value);
   }
 
   /**
@@ -675,7 +674,7 @@
   public void setDouble(Object o, double value)
 throws IllegalAccessException
   {
-f.setDouble(o, value);
+f.setDouble(this, o, value);
   }
 
   /**
Index: 

Jikes RVM 3.0.0 released

2008-08-07 Thread Ian Rogers

We're very happy to announce the release of Jikes RVM version 3.0.0.

The road towards 3.0 began just about two years ago and a large number of
people, both on the core team and from our user community at large, have
contributed to making it a success. Thank You!

The release is available for download at
http://downloads.sourceforge.net/jikesrvm/jikesrvm-3.0.0.tar.bz2

The detailed release notes for major changes since 2.9.3 can be found below
or in JIRA (http://jira.codehaus.org/browse/RVM/fixforversion/13530),
but we'd like to highlight some of the larger themes that went into the 3.0
release (many of which have already been released in  the 2.9.x releases
we've made along the way).
 ** Normalization of source code and build process
   *** Complete rewrite of the build/test systems to use ant.
   *** Jikes RVM can be developed in Eclipse using the JDT
   *** Extensive restructuring of package structure
   *** Removal of VM_ and OPT_ prefixes from all source files.
 ** Increased system stability and performance
   *** A new continuous testing system
(http://jikesrvm.anu.edu.au/cattrack)
   *** Concerted stability and performance drives
 ** Java 5 support
   *** Support for Java 5 language features
   *** Use of Java 5 language features throughout the code base.

Detailed list (89 issues closed in the 3 months since 2.9.3)

** New Feature
   * [RVM-358] - Initial support for Apache Harmony class library
   * [RVM-480] - Spec JVM 2008 regression test
   * [RVM-534] - MMTk Test harness
   * [RVM-540] - Implement java.lang.Compiler
   * [RVM-591] - Support for jdocs.com javadoc
   * [RVM-592] - Checks on creating ObjectReferences

** Improvement]
   * [RVM-72] - NonMoving annotations for classes instances of which
should be allocated to the immortal heap
   * [RVM-273] - Remove VM_ prefix from all VM classes
   * [RVM-275] - Remove VMOpt prefix from opt compiler classes that go
into bootimage
   * [RVM-282] - Make dumpVirtualMachine more defensive
   * [RVM-329] - Specialize IA32 assembler for lister vs. non-lister
   * [RVM-333] - Annotations used for VM Pragmas (NoInline,
Uninterruptible, etc) probably should not be as closed linked to
classloaders
   * [RVM-445] - Clean up handling of JTOC
   * [RVM-449] - Handle instanceof and checkcast in ShortArray scalar
replacer
   * [RVM-477] - Gather new compiler DNA
   * [RVM-501] - BuildWithAllClasses is (practically) unused
   * [RVM-502] - Dead code elimination of pure calls)
   * [RVM-505] - Eliminate calls to VM_Class.getClass..FromStackFrame when
stack frame is determinable
   * [RVM-508] - Have hash map where entries are completely immutable
saving references from boot image root set
   * [RVM-510] - Create top level common directory to make it easier to
split out and share useful components from rvm and MMTk
   * [RVM-511] - Split out MMTk option processing support
   * [RVM-512] - Experiment with freezing bucket array in
VM_HashMap/VM_HashSet
   * [RVM-513] - Large arrays in boot image cause memory leak
   * [RVM-525] - Upgrade to GNU classpath 0.97.2
   * [RVM-537] - Implement inline mustImplementInterface sequence for
invokeinterface in baseline compilers
   * [RVM-538] - Inline checkcast/instanceof sequences in baseline
compiler for simple cases
   * [RVM-572] - Remove OSR_ and BC_ prefixes from OnStackReplacement code
   * [RVM-593] - Extra checks on references being traced in rvm
   * [RVM-603] - Improve intel baseline prologue/epilogue/call by use
push/pop instead of mov [sp]
   * [RVM-594] - Naming of MM_Interface

** Bug
   * [RVM-46] - CaffieneMark failures on AIX/PPC
   * [RVM-47] - DaCapo regressions on AIX/PPC
   * [RVM-58] - Linker errors under AIX/ppc
   * [RVM-105] - sysNetSelect doesnt seem to be avoiding the syswrap
select
   * [RVM-187] - VM_OptGenericMapIterator: findGCMapIndex failed
   * [RVM-221] - Specialized scanning broken on ppc64-aix?
   * [RVM-234] - Annotation issues: not implemented via proxy classes,
support for serialization
   * [RVM-269] - unresolved invokeinterface on null should force
classloading before rasiing NPE
   * [RVM-271] - Timeouts for stress are not correct
   * [RVM-303] - Cannot modify accessible final instance fields
   * [RVM-325] - Spec JVM 98 jack failing with OOMs
   * [RVM-327] - Performance degredation in IA32 assembler
   * [RVM-332] - Eclipse 3.2 fails to run on the RVM
   * [RVM-369] - PPC32-OSX - Crash in GC when a stack contains native
frames
   * [RVM-372] - Integer overflow in sysNanoTime
   * [RVM-423] - Fop performance strangeness
   * [RVM-442] - All poisoned tests fail PPC 32
   * [RVM-454] - The sub-test TestAnnotationInheritance of the basic tests
is excluded until it can be fixed
   * [RVM-458] - Poisoned bit test highlights JNI problem
   * [RVM-469] - Fix IA32 assembler to use Address instead of Offset for
absolute addressing
   * [RVM-482] - Crash when running Production_Opt0_perf portion of
compiler-dna test run
   * [RVM-483] - Conditionalize fsqrt generation on PowerPC
   * 

Re: Savannah has Mercurial!

2008-06-06 Thread Ian Rogers

Andrew John Hughes wrote:

I just noticed this announcement when submitting the news announcement
for 0.97.2.

What do people think to the idea of switching?  Maybe post 0.98?

  

Hi,

just to give a different perspective. For Jikes RVM there's been no
choice to use Mercurial as SourceForge don't provide it, this may
actually have been no bad thing. There are lots of different version
control tools, but both Mercurial and GIT support pulling and pushing to
a SVN repository. Clearly using SVN with SVN isn't a problem and CVS is
out-of-date anyway. So in summary, having a central repository that's an
SVN repository can be a good thing as it supports the maximum number of
version control tools. We have a list of different tools for working
with our repository (hg, git, svn, svk, darcs, svm, rsync) and how to
set them up with Jikes RVM here:

http://jikesrvm.org/Using+Distributed+And+Local+Version+Control+Tools

I may be talking rubbish as I'm not a version control guru. Regards,

Ian
--
http://www.cs.man.ac.uk/~irogers/




Re: [cp-patches] RFC: changes to java.lang.Integer, Long...

2008-06-03 Thread Ian Rogers

Andrew Haley wrote:

Ian Rogers wrote:

  

please give your comments on the attached patch. It tries to reduce the
size of char[] for strings used to hold numbers. It changes Float/Double
equals to use bit based comparisons rather than division. It increases
the use of valueOf methods. It adds a cache of values from -128 to 127
for Long. It adds a cache of the values of zero and one to Float and
Double.

The string size is an estimate. For decimal numbers it will divide the
value repeatedly by 8, causing the string length to be over estimated by
a character for values like 999. This string size is still better than
the current estimate of 33 characters. It also avoids the use of
division (shifts are used) and/or lookup tables.



I am really not convinced by the cache of values from -128 to 127.  It's
a significant overhead for the startup time, and I find it hard to imagine
a justification for it.

Andrew.
  
Sorry, I replied to this off-list accidentally. One alternative is to 
move the class initialization into an inner class by placing the cache 
in an inner class. That way the cache is only built when valueOf a 
cached value is called. This approach would prompt similar changes in 
the other Number valueOf methods.


Ian
--
http://www.cs.man.ac.uk/~irogers/



[cp-patches] RFC: Change to ArrayList.ensureCapacity

2008-05-27 Thread Ian Rogers
This patch changes the array list size increase to ~50% rather than 
doubling in line with what OpenJDK does. OpenJDK still doubles the size 
of vectors, as that's documented behavior.


Feedback appreciated,
Ian
--
http://www.cs.man.ac.uk/~irogers/
--- components/classpath/97.1p6/classpath/java/util/ArrayList.java  
2008-05-19 09:28:13.0 +0100
+++ libraryInterface/GNUClasspath/LGPL/src/java/util/ArrayList.java 
2008-05-27 11:24:58.0 +0100
@@ -173,7 +173,7 @@
 
 if (minCapacity  current)
   {
-E[] newData = (E[]) new Object[Math.max(current * 2, minCapacity)];
+E[] newData = (E[]) new Object[Math.max((current * 3) / 2 + 1, 
minCapacity)];
 System.arraycopy(data, 0, newData, 0, size);
 data = newData;
   }


Re: Classpath 0.98

2008-05-11 Thread Ian Rogers

Andrew John Hughes wrote:

Dear all,

I think it's about time we started to consider another (major)
release.  My personal wishlist of things to finish for this release
is:

* java.util.regex 1.6 support
* java.util.Scanner import (dependent on the above)
* import of javax.activation

Another possibility is to also import gjdoc; our options there are:

* Add GJDoc for 0.98
* Add GJDoc post-release (ending up in 0.99)
* Don't add it at all

It would obviously be an optional build.

Does anyone have any other suggestions for things that should make this release?
Please highlight any regressions you know of as well.  PR36199 that
twisti just filed seems like it should be fixed, for example.

Thanks,
  
It'd be great if SPEC jvm 2008 were known to run. There are issues on 
Cacao and Jikes RVM related to Classpath.


Thanks,
Ian



SPEC jvm 2008 successes?

2008-05-08 Thread Ian Rogers

Hi,

I was wondering what success people have had running SPEC jvm 2008 [1]. 
My experiences are here [2] and I'd like to get further. If anyone 
succeeds I'd be interested to know.


Thanks,
Ian

[1] http://www.spec.org/jvm2008/
[2] http://jira.codehaus.org/browse/RVM-480
--
Third International Workshop on Implementation, Compilation, 
Optimization of Object-Oriented Languages, Programs and Systems 
(ICOOOLPS 2008)

Submissions/Notification/Conference: May 12th/May 19th/July 7th
Paphos (Cyprus) http://icoolps.loria.fr



Re: [cp-patches] RFC: Move exception handling out of common case: java.util.Vector/ArrayList

2008-04-26 Thread Ian Rogers

patch applied.

Ian
--
Third International Workshop on Implementation, Compilation, 
Optimization of Object-Oriented Languages, Programs and Systems 
(ICOOOLPS 2008)

July 7, Paphos (Cyprus)
http://icoolps.loria.fr http://icooolps.loria.fr/



[commit-cp] classpath ChangeLog java/util/ArrayList.java ja...

2008-04-26 Thread Ian Rogers
CVSROOT:/sources/classpath
Module name:classpath
Changes by: Ian Rogers irogers08/04/26 16:46:47

Modified files:
.  : ChangeLog 
java/util  : ArrayList.java Vector.java 

Log message:
2008-04-26  Ian Rogers  [EMAIL PROTECTED]

* java/util/ArrayList (raiseBoundsError): new method to raise 
bound
exceptions in uncommon case.
(checkBoundInclusive): use raiseBoundsError.
(checkBoundExclusive): likewise.
* java/util/ArrayList (raiseBoundsError): new method to raise 
bound
exceptions in uncommon case.
(checkBoundInclusive): use raiseBoundsError.
(checkBoundExclusive): likewise.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/ChangeLog?cvsroot=classpathr1=1.9581r2=1.9582
http://cvs.savannah.gnu.org/viewcvs/classpath/java/util/ArrayList.java?cvsroot=classpathr1=1.31r2=1.32
http://cvs.savannah.gnu.org/viewcvs/classpath/java/util/Vector.java?cvsroot=classpathr1=1.31r2=1.32




[cp-patches] RFC: Move exception handling out of common case: java.util.Vector/ArrayList

2008-04-25 Thread Ian Rogers

Hi,

the attached patch moves exception handling code out of the common case 
for elementAt of both java.util.Vector and java.util.elementAt, this 
helps JIT compilation inline the common non-exception throwing case (and 
avoid expense incurred by considering StringBuilders, etc.). Other than 
fixing coding convention issues, are there any objections to this change?


Thanks,
Ian
--
http://www.cs.man.ac.uk/~irogers/
Index: java/util/ArrayList.java
===
RCS file: /sources/classpath/classpath/java/util/ArrayList.java,v
retrieving revision 1.31
diff -u -r1.31 ArrayList.java
--- java/util/ArrayList.java10 Dec 2006 20:25:46 -  1.31
+++ java/util/ArrayList.java23 Apr 2008 14:17:43 -
@@ -472,8 +472,7 @@
 // use of a negative index will cause an ArrayIndexOutOfBoundsException,
 // a subclass of the required exception, with no effort on our part.
 if (index  size)
-  throw new IndexOutOfBoundsException(Index:  + index + , Size: 
-  + size);
+ raiseBoundsError(index);
   }
 
   /**
@@ -488,11 +487,23 @@
 // use of a negative index will cause an ArrayIndexOutOfBoundsException,
 // a subclass of the required exception, with no effort on our part.
 if (index = size)
-  throw new IndexOutOfBoundsException(Index:  + index + , Size: 
-  + size);
+ raiseBoundsError(index);
   }
 
   /**
+   * Raise the ArrayIndexOfOutBoundsException.
+   * @param index the index of the access
+   * @throws IndexOutOfBoundsException unconditionally
+   */
+  private void raiseBoundsError(int index)
+  {
+   // Implementaion note: put in a separate method to make the JITs job 
easier
+   // (separate common from uncommon code at method boundaries when 
trivial to do so).
+   throw new IndexOutOfBoundsException(Index:  + index + , Size:  + 
size);
+  }
+  
+  
+  /**
* Remove from this list all elements contained in the given collection.
* This is not public, due to Sun's API, but this performs in linear
* time while the default behavior of AbstractList would be quadratic.
Index: java/util/Vector.java
===
RCS file: /sources/classpath/classpath/java/util/Vector.java,v
retrieving revision 1.31
diff -u -r1.31 Vector.java
--- java/util/Vector.java   12 Mar 2008 23:39:51 -  1.31
+++ java/util/Vector.java   23 Apr 2008 14:17:43 -
@@ -909,7 +909,7 @@
 // use of a negative index will cause an ArrayIndexOutOfBoundsException
 // with no effort on our part.
 if (index  elementCount)
-  throw new ArrayIndexOutOfBoundsException(index ++ elementCount);
+ raiseBoundsError(index,   );
   }
 
   /**
@@ -924,10 +924,23 @@
 // use of a negative index will cause an ArrayIndexOutOfBoundsException
 // with no effort on our part.
 if (index = elementCount)
-  throw new ArrayIndexOutOfBoundsException(index +  =  + elementCount);
+ raiseBoundsError(index,  = );
   }
 
   /**
+   * Raise the ArrayIndexOfOutBoundsException.
+   * @param index the index of the access
+   * @param operator the operator to include in the error message
+   * @throws IndexOutOfBoundsException unconditionally
+   */
+  private void raiseBoundsError(int index, String operator)
+  {
+   // Implementaion note: put in a separate method to make the JITs job 
easier
+   // (separate common from uncommon code at method boundaries when 
trivial to do so).
+   throw new ArrayIndexOutOfBoundsException(index + operator + 
elementCount);
+  }
+  
+  /**
* Serializes this object to the given stream.
*
* @param s the stream to write to


Re: [cp-patches] RFC: Move exception handling out of common case: java.util.Vector/ArrayList

2008-04-25 Thread Ian Rogers

Andrew John Hughes wrote:

Looks okay, overlooking the obvious formatting issues.
Is there an overhead to the method call or would most VMs inline this?
  


So, most code shouldn't access an element beyond the length of the 
Vector or ArrayList - so the exception handling code will never normally 
be executed in any benchmarks, so the method calling overhead isn't 
important. If the method call were to become hot, the Jikes RVM would 
inline it, but this is very unlikely to happen. This patch is being 
applied against the Jikes RVM currently to gain performance in 
particular on SpecJVM 98. I'd like to include the patch in Classpath to 
minimize points where the Jikes RVM and Classpath libraries differ.


Thanks,
Ian



[cp-patches] Re: RFC: changes to java.nio buffers

2008-04-18 Thread Ian Rogers

Committed.

2008-04-18  Ian Rogers  [EMAIL PROTECTED]

* java/nio/Buffer.java (cap): make field private and final.
(address): make field final.
(Buffer): add address argument to package protected constructor 
thereby
allowing it to be made final.
* java/nio/ByteBuffer.java (backing_buffer): make field final.
(array_offset): make field final.
(ByteBuffer): add address, backing_buffer and array_offset to
constructor, allowing fields to be made final.
* java/nio/ByteBufferImpl.java (readOnly): make field final.
(ByteBufferImpl): modify call to super class constructor to pass
backing_buffer and array_offset.
* java/nio/CharBuffer.java (array_offset): make field final.
(backing_buffer): make field final.
(CharBuffer): add address, backing_buffer and array_offset to
constructor, allowing fields to be made final.
* java/nio/CharBufferImpl.java (readOnly): make field final.
(CharBufferImpl): modify call to super class constructor to pass
backing_buffer and array_offset.
(CharBufferImpl(CharBufferImpl)): likewise.
* java/nio/CharSequenceBuffer.java (charSequence): make field 
final.
(CharSequenceBuffer): modify call to super class constructor, 
allowing
fields to be made final.
(duplicate): use capacity call rather than cap, to allow better
encapsulation.
* java/nio/CharViewBufferImpl.java (offset): make field final.
(bb): likewise.
(readOnly): likewise.
(endian): likewise.
(CharViewBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/DirectByteBufferImpl.java: modify calls to super 
class
constructors, allowing fields to be made final.
* java/nio/DoubleBuffer.java (array_offset): make field final.
(backing_buffer): make field final.
(DoubleBuffer): add address, backing_buffer and array_offset to
constructor, allowing fields to be made final.
* java/nio/DoubleBufferImpl.java (readOnly): make field final.
(DoubleBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/DoubleViewBufferImpl.java (offset): make field final.
(bb): likewise.
(readOnly): likewise.
(endian): likewise.
(DoubleViewBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/FloatBuffer.java (array_offset): make field final.
(backing_buffer): make field final.
(FloatBuffer): add address, backing_buffer and array_offset to
constructor, allowing fields to be made final.
* java/nio/FloatBufferImpl.java (readOnly): make field final.
(FloatBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/FloatViewBufferImpl.java (offset): make field final.
(bb): likewise.
(readOnly): likewise.
(endian): likewise.
(FloatViewBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/IntBuffer.java (array_offset): make field final.
(backing_buffer): make field final.
(IntBuffer): add address, backing_buffer and array_offset to
constructor, allowing fields to be made final.
* java/nio/IntBufferImpl.java (readOnly): make field final.
(IntBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/IntViewBufferImpl.java (offset): make field final.
(bb): likewise.
(readOnly): likewise.
(endian): likewise.
(IntViewBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/LongBuffer.java (array_offset): make field final.
(backing_buffer): make field final.
(LongBuffer): add address, backing_buffer and array_offset to
constructor, allowing fields to be made final.
* java/nio/LongBufferImpl.java (readOnly): make field final.
(LongBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio

[commit-cp] classpath ChangeLog java/lang/Byte.java java/la...

2008-04-18 Thread Ian Rogers
CVSROOT:/sources/classpath
Module name:classpath
Changes by: Ian Rogers irogers08/04/18 21:00:12

Modified files:
.  : ChangeLog 
java/lang  : Byte.java Character.java Double.java Float.java 
 Integer.java Long.java Short.java 

Log message:
2008-04-18  Ian Rogers  [EMAIL PROTECTED]

* java/lang/Byte.java (static): initialize byteCache.
(valueOf(String,int)): use valueOf(byte) rather than new.
(valueOf(String)): likewise.
(valueOf(byte)): Switch from lazy initialization of cached 
values to
initialization at class initialization time. This removes the 
need for
synchronization in the common case.
(decode): use valueOf(byte) rather than new.
* java/lang/Character.java (static): initialize charCache.
(valueOf): Switch from lazy initialization of cached values to
initialization at class initialization time. This removes the 
need for
synchronization in the common case.
* java/lang/Double.java (ZERO): new private field.
(ONE): likewise.
(valueOf(double)): don't create new doubles for the case of 0 
and 1.
(valueOf(String)): use valueOf(double) rather than new.
(equals): use raw bits for comparison to avoid division.
* java/lang/Float.java (ZERO): new private field.
(ONE): likewise.
(valueOf(float)): don't create new floats for the case of 0 and 
1.
(valueOf(String)): use valueOf(float) rather than new.
(equals): use raw bits for comparison to avoid division.
* java/lang/Integer.java (static): initialize intCache.
(stringSize): new private method to estimate size of string for 
an int.
(toString): reuse digits for single character strings, for 
multiple
character strings estimate their length using string size 
method.
(valueOf(String,int)): use valueOf(int) rather than new.
(valueOf(String)): likewise.
(valueOf(int)): Switch from lazy initialization of cached 
values to
initialization at class initialization time. This removes the 
need for
synchronization in the common case.
(getInteger): use valueOf(int) rather than new.
(decode): use valueOf(int) rather than new.
(signum): use shift and subtract to compute value.
(toUnsignedString): calculate string size rather than using 32 
chars.
* java/lang/Long.java (longCache): new private field.
(stringSize): new private method to estimate size of string for 
a long.
(toString): reuse digits for single character strings, for 
multiple
character strings estimate their length using string size 
method.
(valueOf(String,int)): use valueOf(long) rather than new.
(valueOf(String)): likewise.
(valueOf(long)): use cache of values.
(decode): use valueOf(long) rather than new.
(signum): use shift and subtract to compute value.
(toUnsignedString): calculate string size rather than using 64 
chars.
* java/lang/Short.java (static): initialize shortCache.
(valueOf(String,int)): use valueOf(short) rather than new.
(valueOf(String)): likewise.
(valueOf(short)): Switch from lazy initialization of cached 
values to
initialization at class initialization time. This removes the 
need for
synchronization in the common case.
(decode): use valueOf(short) rather than new.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/ChangeLog?cvsroot=classpathr1=1.9577r2=1.9578
http://cvs.savannah.gnu.org/viewcvs/classpath/java/lang/Byte.java?cvsroot=classpathr1=1.26r2=1.27
http://cvs.savannah.gnu.org/viewcvs/classpath/java/lang/Character.java?cvsroot=classpathr1=1.48r2=1.49
http://cvs.savannah.gnu.org/viewcvs/classpath/java/lang/Double.java?cvsroot=classpathr1=1.45r2=1.46
http://cvs.savannah.gnu.org/viewcvs/classpath/java/lang/Float.java?cvsroot=classpathr1=1.39r2=1.40
http://cvs.savannah.gnu.org/viewcvs/classpath/java/lang/Integer.java?cvsroot=classpathr1=1.36r2=1.37
http://cvs.savannah.gnu.org/viewcvs/classpath/java/lang/Long.java?cvsroot=classpathr1=1.25r2=1.26
http://cvs.savannah.gnu.org/viewcvs/classpath/java/lang/Short.java?cvsroot=classpathr1=1.20r2=1.21




[commit-cp] classpath ChangeLog java/nio/Buffer.java java/n...

2008-04-18 Thread Ian Rogers
CVSROOT:/sources/classpath
Module name:classpath
Changes by: Ian Rogers irogers08/04/18 23:23:34

Modified files:
.  : ChangeLog 
java/nio   : Buffer.java ByteBuffer.java ByteBufferImpl.java 
 CharBuffer.java CharBufferImpl.java 
 CharSequenceBuffer.java CharViewBufferImpl.java 
 DirectByteBufferImpl.java DoubleBuffer.java 
 DoubleBufferImpl.java DoubleViewBufferImpl.java 
 FloatBuffer.java FloatBufferImpl.java 
 FloatViewBufferImpl.java IntBuffer.java 
 IntBufferImpl.java IntViewBufferImpl.java 
 LongBuffer.java LongBufferImpl.java 
 LongViewBufferImpl.java MappedByteBuffer.java 
 MappedByteBufferImpl.java ShortBuffer.java 
 ShortBufferImpl.java ShortViewBufferImpl.java 

Log message:
2008-04-18  Ian Rogers  [EMAIL PROTECTED]

* java/nio/Buffer.java (cap): make field private and final.
(address): make field final.
(Buffer): add address argument to package protected constructor 
thereby
allowing it to be made final.
* java/nio/ByteBuffer.java (backing_buffer): make field final.
(array_offset): make field final.
(ByteBuffer): add address, backing_buffer and array_offset to
constructor, allowing fields to be made final.
* java/nio/ByteBufferImpl.java (readOnly): make field final.
(ByteBufferImpl): modify call to super class constructor to pass
backing_buffer and array_offset.
* java/nio/CharBuffer.java (array_offset): make field final.
(backing_buffer): make field final.
(CharBuffer): add address, backing_buffer and array_offset to
constructor, allowing fields to be made final.
* java/nio/CharBufferImpl.java (readOnly): make field final.
(CharBufferImpl): modify call to super class constructor to pass
backing_buffer and array_offset.
(CharBufferImpl(CharBufferImpl)): likewise.
* java/nio/CharSequenceBuffer.java (charSequence): make field 
final.
(CharSequenceBuffer): modify call to super class constructor, 
allowing
fields to be made final.
(duplicate): use capacity call rather than cap, to allow better
encapsulation.
* java/nio/CharViewBufferImpl.java (offset): make field final.
(bb): likewise.
(readOnly): likewise.
(endian): likewise.
(CharViewBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/DirectByteBufferImpl.java: modify calls to super 
class
constructors, allowing fields to be made final.
* java/nio/DoubleBuffer.java (array_offset): make field final.
(backing_buffer): make field final.
(DoubleBuffer): add address, backing_buffer and array_offset to
constructor, allowing fields to be made final.
* java/nio/DoubleBufferImpl.java (readOnly): make field final.
(DoubleBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/DoubleViewBufferImpl.java (offset): make field final.
(bb): likewise.
(readOnly): likewise.
(endian): likewise.
(DoubleViewBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/FloatBuffer.java (array_offset): make field final.
(backing_buffer): make field final.
(FloatBuffer): add address, backing_buffer and array_offset to
constructor, allowing fields to be made final.
* java/nio/FloatBufferImpl.java (readOnly): make field final.
(FloatBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/FloatViewBufferImpl.java (offset): make field final.
(bb): likewise.
(readOnly): likewise.
(endian): likewise.
(FloatViewBufferImpl): modify call to super class constructor, 
allowing
fields to be made final.
* java/nio/IntBuffer.java (array_offset): make field final.
(backing_buffer): make field final.
(IntBuffer): add address, backing_buffer and array_offset to
constructor, allowing fields to be made final

[cp-patches] RFC: changes to java.lang.Integer, Long...

2008-04-14 Thread Ian Rogers

Hi,

please give your comments on the attached patch. It tries to reduce the 
size of char[] for strings used to hold numbers. It changes Float/Double 
equals to use bit based comparisons rather than division. It increases 
the use of valueOf methods. It adds a cache of values from -128 to 127 
for Long. It adds a cache of the values of zero and one to Float and Double.


The string size is an estimate. For decimal numbers it will divide the 
value repeatedly by 8, causing the string length to be over estimated by 
a character for values like 999. This string size is still better than 
the current estimate of 33 characters. It also avoids the use of 
division (shifts are used) and/or lookup tables.


Regards,
Ian
Index: ChangeLog
===
RCS file: /sources/classpath/classpath/ChangeLog,v
retrieving revision 1.9572
diff -u -r1.9572 ChangeLog
--- ChangeLog   9 Apr 2008 20:23:11 -   1.9572
+++ ChangeLog   14 Apr 2008 13:54:25 -
@@ -1,3 +1,50 @@
+2008-04-14  Ian Rogers  [EMAIL PROTECTED]
+
+   * java/lang/Byte.java (static): initialize byteCache.
+   (valueOf(String,int)): use valueOf(byte) rather than new.
+   (valueOf(String)): likewise.
+   (valueOf(byte)): remove synchronization.
+   (decode): use valueOf(byte) rather than new.
+   * java/lang/Character.java (static): initialize charCache.
+   (valueOf): remove synchronization.
+   * java/lang/Double.java (ZERO): new private field.
+   (ONE): likewise.
+   (valueOf(double)): don't create new doubles for the case of 0 and 1.
+   (valueOf(String)): use valueOf(double) rather than new.
+   (equals): use raw bits for comparison to avoid division.
+* java/lang/Float.java (ZERO): new private field.
+(ONE): likewise.
+(valueOf(double)): don't create new floats for the case of 0 and 1.
+(valueOf(String)): use valueOf(float) rather than new.
+(equals): use raw bits for comparison to avoid division.
+   * java/lang/Integer.java (static): initialize intCache.
+   (stringSize): new private method to estimate size of string for an int.
+   (toString): reuse digits for single character strings, for multiple
+   character strings estimate their length using string size method.
+   (valueOf(String,int)): use valueOf(int) rather than new.
+   (valueOf(String)): likewise.
+   (valueOf(int)): remove synchronization.
+   (getInteger): use valueOf(int) rather than new.
+   (decode): use valueOf(int) rather than new.
+   (signum): use shift and subtract to compute value.
+   (toUnsignedString): calculate string size rather than using 32 chars.
+* java/lang/Long.java (longCache): new private field.
+(stringSize): new private method to estimate size of string for a long.
+(toString): reuse digits for single character strings, for multiple
+character strings estimate their length using string size method.
+(valueOf(String,int)): use valueOf(long) rather than new.
+(valueOf(String)): likewise.
+(valueOf(long)): use cache.
+(decode): use valueOf(long) rather than new.
+   (getLong): likewise.
+(signum): use shift and subtract to compute value.
+   (toUnsignedString): calculate string size rather than using 64 chars.
+   * java/lang/Short.java (static): initialize shortCache.
+(valueOf(String,int)): use valueOf(short) rather than new.
+(valueOf(String)): likewise.
+(valueOf(short)): remove synchronization.
+(decode): use valueOf(short) rather than new.
+
 2008-04-09  Mario Torre  [EMAIL PROTECTED]
  
* java/io/File.java (canWrite): use canWriteDirectory(String). 
Index: java/lang/Byte.java
===
RCS file: /sources/classpath/classpath/java/lang/Byte.java,v
retrieving revision 1.26
diff -u -r1.26 Byte.java
--- java/lang/Byte.java 10 Dec 2006 20:25:44 -  1.26
+++ java/lang/Byte.java 14 Apr 2008 13:54:25 -
@@ -88,6 +88,11 @@
   // This caches Byte values, and is used by boxing conversions via
   // valueOf().  We're required to cache all possible values here.
   private static Byte[] byteCache = new Byte[MAX_VALUE - MIN_VALUE + 1];
+  static
+  {
+for (byte i=MIN_VALUE; i = MAX_VALUE; i++)
+  byteCache[i - MIN_VALUE] = new Byte(i);
+  }
 
 
   /**
@@ -185,7 +190,7 @@
*/
   public static Byte valueOf(String s, int radix)
   {
-return new Byte(parseByte(s, radix));
+return valueOf(parseByte(s, radix));
   }
 
   /**
@@ -201,7 +206,7 @@
*/
   public static Byte valueOf(String s)
   {
-return new Byte(parseByte(s, 10));
+return valueOf(parseByte(s, 10));
   }
 
   /**
@@ -214,12 +219,7 @@
*/
   public static Byte valueOf(byte val)
   {
-synchronized (byteCache)
-  {
-   if (byteCache[val - MIN_VALUE] == null)
- byteCache[val - MIN_VALUE

Re: [cp-patches] RFC: changes to java.lang.Integer, Long...

2008-04-14 Thread Ian Rogers

David Daney wrote:

Ian Rogers wrote:

Hi,

please give your comments on the attached patch. It tries to reduce 
the size of char[] for strings used to hold numbers. It changes 
Float/Double equals to use bit based comparisons rather than 
division. It increases the use of valueOf methods. It adds a cache of 
values from -128 to 127 for Long. It adds a cache of the values of 
zero and one to Float and Double.


The string size is an estimate. For decimal numbers it will divide 
the value repeatedly by 8, causing the string length to be over 
estimated by a character for values like 999. This string size is 
still better than the current estimate of 33 characters. It also 
avoids the use of division (shifts are used) and/or lookup tables.




I would like to know your motivation for doing this.  Do you have any 
evidence that this will reduce memory usage and speed up real 
applications?



That said, in our gcj-3.4 based application, we had to create a cache 
of Integers because we were creating large numbers of them all with a 
small set of values.


So in principle this could be a good approach, but I don't know if we 
can assume that there is universal benefit from a patch like this.  
Can you point to any benchmarks where this helps?



Thanks,
David Daney

Hi David,

I'm having a crack down on wasted memory in the Jikes RVM.

For DaCapo fop (single iteration) there are 270 and 977 occurrences of  
Double 0 and 1 and 20 occurrences of other Doubles. On the other hand 
DaCapo bloat has very few 0 and 1 values. My motivation to cache these, 
other than fop, is that they exist as bytecodes (fconst0/fconst1 and 
dconst0/dconst1, although I'm ignoring fconst2 and dconst2). We already 
cache Integers in the intCache. I do extend this concept to Long, as is 
done in OpenJDK, and to Float and Double.


Currently we always allocated 33 char arrays to hold the string value, 
this is 4.625 the size of the minimum object in the RVM. In the case of 
a single character string, 18.86% of Integer strings in DaCapo bloat, 
this code doesn't allocate any char arrays. For other integers the char 
array is reduced to either the exact or (20% of the time for decimal 
values)  1 character longer char arrays. This is at the cost of up to 32 
compares, branches and shifts. For DaCapo bloat a little under 50% of 
integer strings created are for values between -128 and 127.


So the trade offs in the code are, slower Float/Double valueOf code, but 
fewer Float and Double objects (hopefully improving GC). A small time to 
calculate string sizes vs smaller strings and less GC pressure.


For the Jikes RVM we measure performance 4 times a day [1], I introduced 
this patch in r14113 and there are no peaks or troughs that appear at 
this point. Given the patch is performance neutral but saves memory 
(although not improving GC performance for the RVM markedly) I think 
it's worth including. GC is less than 6% of execution time, so time 
saved may be difficult to measure in the bigger picture (unless it 
pushes you under or over a particular threshold).


Regards,
Ian

[1] 
http://jikesrvm.anu.edu.au/cattrack/results/rvmx86lnx32.anu.edu.au/perf/3437/performance_report 





Re: [cp-patches] RFC: File bug Fix and small VM interface change

2008-04-09 Thread Ian Rogers

Hi Mario,

this looks like a good patch so +1 from me. Just to note that we've been 
discussing the VMFile interface in a Jikes RVM tracker [1] and that on 
IRC MJW pointed out that GCJ's implementation appeared to vary from that 
of Classpath [2] [3] [4].


Regards,
Ian

[1] http://jira.codehaus.org/browse/RVM-427
[2] http://gcc.gnu.org/viewcvs/*checkout*/trunk/libjava/java/io/File.java
[3] 
http://gcc.gnu.org/viewcvs/*checkout*/trunk/libjava/java/io/natFileWin32.cc
[4] 
http://gcc.gnu.org/viewcvs/*checkout*/trunk/libjava/java/io/natFilePosix.cc


Mario Torre wrote:

Hello all!

I would like to submit this fix.

The problem is that to detect if a file is writable we actually open it
for writing... Even worse, in the case of a directory, we write to it a
temp file!

There are a number of issues that I see wrong here, but what worries me
most is that these operations can kill filesystem that reside on compact
flash memories and other devices that have a limited number of write.

The current fix does two things.

1. introduce a new method, native, canWriteDirectory(String path)
This method is meant to be implemented by whoever implements the VM
interface, so that it can do nice things with their target environment.
The default implementation works on Linux and should work on any *nix
operating systems. I've left canWriteDirectory(File file) for backward
compatibility, but I guess no one uses this anyway (it defer to the
native method).

2. Change the implementation of Java_java_io_VMFile_canWrite and
Java_java_io_VMFile_canRead so that they use cpio_checkAccess now,
instead of doing the old The lazy man's way out (which is also more
code, btw...)

I'm going to submit this today if no one complains, any ideas?

Ah, before I forget, there are a number of unrelated fixes like
indentation and all the function signature now reflect the fact that
these methods are static (jclass instead of jobject). It would be handy
here to use mercurial (hg record) to separate patchsets.

Mario


2008-04-09  Mario Torre  [EMAIL PROTECTED]
 
	* java/io/File.java (canWrite): use canWriteDirectory(String). 
	* vm/reference/java/io/VMFile.java (canWriteDirectory): new native
method. 
	* native/jni/java-io/java_io_VMFile.c: correct indentation, sync

function
names with header file definition.
(Java_java_io_VMFile_canRead): use cpio_checkAccess to get access
permission. Removed unused variable.
(Java_java_io_VMFile_canWrite): likewise.
(Java_java_io_VMFile_canWriteDirectory): new function.
  





[cp-patches] RFC: changes to java.nio buffers

2008-04-08 Thread Ian Rogers

Hi,

the attached patch makes more fields in java.nio final, restructuring 
constructors to enable this. This simplifies the code sufficiently that 
it aids the Jikes RVM's escape analysis so that it can remove memory 
allocations associated with buffers in certain key areas. When some 
fields could be made private rather than package protected they were.


Thanks,
Ian
--- java/nio/Buffer.java2007-04-12 22:13:22.0 +0100
+++ java/nio/Buffer.java2008-04-08 20:33:49.0 +0100
@@ -45,19 +45,21 @@
  */
 public abstract class Buffer
 {
-  int cap = 0;
-  int limit = 0;
-  int pos = 0;
-  int mark = -1;
-  Pointer address;
+  private final int cap;
+  int limit;
+  int pos;
+  int mark;
+  final Pointer address;
 
   /**
* Creates a new Buffer.
*
* Should be package private.
*/
-  Buffer (int capacity, int limit, int position, int mark)
+  Buffer (int capacity, int limit, int position, int mark, Pointer address)
   {
+this.address = address;
+
 if (capacity  0)
   throw new IllegalArgumentException ();
 
@@ -72,6 +74,10 @@
   
   this.mark = mark;
 }
+else
+{
+  this.mark = -1;
+}
   }
   
   /**
--- java/nio/ByteBufferImpl.java2006-05-13 18:20:35.0 +0100
+++ java/nio/ByteBufferImpl.java2008-04-08 16:14:43.0 +0100
@@ -43,13 +43,11 @@
  */
 final class ByteBufferImpl extends ByteBuffer
 {
-  private boolean readOnly;
+  private final boolean readOnly;
 
   ByteBufferImpl (byte[] buffer, int offset, int capacity, int limit, int 
position, int mark, boolean readOnly)
   {
-super (capacity, limit, position, mark);
-this.backing_buffer = buffer;
-this.array_offset = offset;
+super (capacity, limit, position, mark, null, buffer, offset);
 this.readOnly = readOnly;
   }
   
--- java/nio/ByteBuffer.java2006-12-10 20:25:45.0 +
+++ java/nio/ByteBuffer.java2008-04-08 20:34:19.0 +0100
@@ -38,6 +38,8 @@
 
 package java.nio;
 
+import gnu.classpath.Pointer;
+
 /**
  * @since 1.4
  */
@@ -45,13 +47,14 @@
   implements ComparableByteBuffer
 {
   ByteOrder endian = ByteOrder.BIG_ENDIAN;
+  final byte[] backing_buffer;
+  final int array_offset;
 
-  int array_offset;
-  byte[] backing_buffer;
-
-  ByteBuffer (int capacity, int limit, int position, int mark)
+  ByteBuffer (int capacity, int limit, int position, int mark, Pointer 
address, byte[] backing_buffer, int array_offset)
   {
-super (capacity, limit, position, mark);
+super (capacity, limit, position, mark, address);
+this.backing_buffer = backing_buffer;
+this.array_offset = array_offset;
   }
 
   /**
--- java/nio/CharBufferImpl.java2006-05-01 23:41:20.0 +0100
+++ java/nio/CharBufferImpl.java2008-04-08 16:20:20.0 +0100
@@ -43,7 +43,7 @@
  */
 final class CharBufferImpl extends CharBuffer
 {
-  private boolean readOnly;
+  private final boolean readOnly;
 
   CharBufferImpl (int capacity)
   {
@@ -52,18 +52,14 @@
   
   CharBufferImpl (char[] buffer, int offset, int capacity, int limit, int 
position, int mark, boolean readOnly)
   {
-super (capacity, limit, position, mark);
-this.backing_buffer = buffer;
-this.array_offset = offset;
+super (capacity, limit, position, mark, null, buffer, offset);
 this.readOnly = readOnly;
   }
   
   public CharBufferImpl (CharBufferImpl copy)
   {
-super (copy.capacity (), copy.limit (), copy.position (), 0);
-backing_buffer = copy.backing_buffer;
-array_offset = copy.array_offset;
-readOnly = copy.isReadOnly ();
+super (copy.capacity (), copy.limit (), copy.position (), 0, null, 
copy.backing_buffer, copy.array_offset);
+this.readOnly = copy.isReadOnly ();
   }
   
   public boolean isReadOnly ()
--- java/nio/CharBuffer.java2007-04-12 21:35:33.0 +0100
+++ java/nio/CharBuffer.java2008-04-08 20:34:47.0 +0100
@@ -39,6 +39,7 @@
 package java.nio;
 
 import java.io.IOException;
+import gnu.classpath.Pointer;
 
 /**
  * @since 1.4
@@ -46,13 +47,14 @@
 public abstract class CharBuffer extends Buffer
   implements ComparableCharBuffer, CharSequence, Readable, Appendable
 {
-  int array_offset;
-  char[] backing_buffer;
+  final int array_offset;
+  final char[] backing_buffer;
 
-  CharBuffer (int capacity, int limit, int position, int mark)
+  CharBuffer (int capacity, int limit, int position, int mark, Pointer 
address, char[] backing_buffer, int array_offset)
   {
-super (capacity, limit, position, mark);
-array_offset = 0;
+super (capacity, limit, position, mark, address);
+this.backing_buffer = backing_buffer;
+this.array_offset = array_offset;
   }
 
   /**
--- java/nio/CharSequenceBuffer.java2007-04-12 21:35:33.0 +0100
+++ java/nio/CharSequenceBuffer.java2008-04-08 16:22:51.0 +0100
@@ -48,7 +48,7 @@
   /**
* The wrapped char sequence.
*/
-  private CharSequence charSequence;
+  private final 

Re: Inconvertible types error in EnumSet.java

2008-03-17 Thread Ian Rogers

Trevor Harmon wrote:

On Mar 16, 2008, at 5:33 PM, Andrew John Hughes wrote:


Version 1.5 of Sun's javac is broken.  Please use an alternate
compiler, such as ecj, or a newer version of javac, such as OpenJDK
javac or the version that comes with JDK 1.6.


What about jikes? I guess the 0.97.1 release no longer works with jikes?

Trevor



The jikes Java to bytecode compiler only supports Java 1.4 and has been 
unable to build Classpath since the introduction of generics in release 
0.95 (April 23rd 2007). Jikes RVM builds Classpath with ECJ version 3.2 
(version 3.3 generates invalid bytecode when compiling Classpath - this 
is fixed in the first milestone after ECJ 3.3, but most Linux 
distributions ship with the broken ECJ). The broken javac problem is 
also present in other 1.5 JDKs (e.g. BEA, IBM), and is actually a 
different bug with the initial 1.5 releases.


Regards,
Ian Rogers
--
http://www.cs.man.ac.uk/~irogers



Re: brandweg hacking session on friday

2008-02-21 Thread Ian Rogers

Dalibor Topic wrote:
I'll be in Brussels from 12h on. So I'd either suggest meeting at 
Hotel Barry at 12:30, or that we meet at Brussels Centraal train 
station, (my train from Luxembourg arrives 11:47), grab some food, and 
move over to Hotel Barry to hack on BrandWeg afterwards, until 5pm, 
and then to move over to BXL.


cheers,
dalibor topic


Hi,

well the hotel barry is pretty (very) basic but the wifi seems ok (just
used it for a skype conversation without any noticeable break up). I'm
in room xx and my phone number is +44 xxx xxx . Is the centraal
train station the midi train station? If so, I should be able to find my
way there and loiter at about noon. I like to eat food too, so I'd
suggest we meet, eat and then hack.

Just FYI I have a few objectives that I'd like to work towards from the
hacking:
1) get a Jikes RVM build configuration that can work with BrandWeg
2) test ECJ and x10c with BrandWeg
3) look at making the java.math configuration of BrandWeg pluggable
between the Classpath and OpenJDK versions (a couple of benchmarks hit
java.math code and it would be nice to rule it out as a source of
performance loss). I imagine this could spark some conversation on how
we track code in BrandWeg, acknowledgements, how to configure choices
like this.
4) think of any other problems like number 3

Regards,
Ian




Re: brandweg hacking session on friday

2008-02-19 Thread Ian Rogers

Dalibor Topic wrote:

Andrew John Hughes wrote:

Thanks for organising this.  I should arrive in Brussels around 4pm on
the Friday, so will probably be available around an hour from then I
guess (given time to find the hotel and check in, etc.).  My
preference would be for somewhere with food and drink, but depends on
the time we have and the ease of finding such a place.  I'll leave
that up to those who know Brussels better than I... ;)


Should we meet at the BXL at Grand Place from 5pm on?


I take it that someone has a laptop or something, if we want this to
be a practical session?


Sure, I'll bring mine along, and a checkout of the classpath, openjdk 
and brandweg trees. ;)


Hi,

apologies for my delay in responding. I will be available all day 
Friday, so I'd suggest we start earlier (I'm coming to Brussels on the 
Thursday). I should have wifi access in the Hotel Barry. Could we meet 
in the morning, maybe at the Hotel Barry?


Thanks,
Ian



Re: [cp-patches] RFC: Double.doubleToLongBits simplified

2008-02-08 Thread Ian Rogers

Dalibor Topic wrote:

Hi all,

I've implemented doubleToLongBits without requring a VMDouble method 
of the same name. It would let us remove one method from the VM 
interface for the next version, and the corresoponding native code. OK 
to commit?

(I'd do the equivalent patch for Float, too).

* java/lang/Double.java (doubleToLongBits): Simplified.

cheers,
dalibor topic


Hi,

if this life makes things easier for you then its a good thing. The 
Jikes RVM already does this at the VMDouble level, and just has a 
doubleAsRawLongBits magic/native method. So, I'm not sure if this change 
shouldn't be pushed down into VMDouble, or at least if it is done in 
Double the obsolete doubleToLongBits call in VMDouble should be removed.


Thanks,
Ian



Re: [cp-patches] RFC: use helper method to clone char array in java.lang.String

2008-02-07 Thread Ian Rogers

Tom Tromey wrote:

Ian == Ian Rogers [EMAIL PROTECTED] writes:



Ian Please let me know if you think this patch is suitable for
Ian inclusion.

It looks fine.  I do have one nit, which is that we put spaces around
operators... this problem is pervasive in the patch, but here's one
example:

Ian +newStr[x-offset] = newChar;

That should read

newStr[x - offset] = newChar;

Tom
  

Thanks Tom,

here is a revised patch that if there are no other problems I'd like to 
commit today.


Regards,
Ian
Index: ChangeLog
===
RCS file: /sources/classpath/classpath/ChangeLog,v
retrieving revision 1.9481
diff -u -r1.9481 ChangeLog
--- ChangeLog   6 Feb 2008 19:00:44 -   1.9481
+++ ChangeLog   7 Feb 2008 09:21:01 -
@@ -1,3 +1,8 @@
+2008-02-07  Ian Rogers  [EMAIL PROTECTED]
+
+   * java/lang/String.java
+   Only copy live portion of String. Use array copies in preference to 
clone.
+
 2008-02-05  Ian Rogers  [EMAIL PROTECTED]
 
* gnu/java/lang/reflect/TypeSignature.java
Index: java/lang/String.java
===
RCS file: /sources/classpath/classpath/java/lang/String.java,v
retrieving revision 1.87
diff -u -r1.87 String.java
--- java/lang/String.java   23 Nov 2007 15:04:25 -  1.87
+++ java/lang/String.java   7 Feb 2008 09:21:01 -
@@ -1303,13 +1303,13 @@
 break;
 if (i  0)
   return this;
-char[] newStr = (char[]) value.clone();
-newStr[x] = newChar;
+char[] newStr = toCharArray();
+newStr[x - offset] = newChar;
 while (--i = 0)
   if (value[++x] == oldChar)
-newStr[x] = newChar;
+newStr[x - offset] = newChar;
 // Package constructor avoids an array copy.
-return new String(newStr, offset, count, true);
+return new String(newStr, 0, count, true);
   }
 
   /**
@@ -1450,23 +1450,25 @@
 
 // Now we perform the conversion. Fortunately, there are no multi-character
 // lowercase expansions in Unicode 3.0.0.
-char[] newStr = (char[]) value.clone();
+char[] newStr = new char[count];
+VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
 do
   {
 char ch = value[x];
 // Hardcoded special case.
 if (ch != '\u0049')
   {
-newStr[x++] = Character.toLowerCase(ch);
+newStr[x - offset] = Character.toLowerCase(ch);
   }
 else
   {
-newStr[x++] = '\u0131';
+newStr[x - offset] = '\u0131';
   }
+x++;
   }
 while (--i = 0);
 // Package constructor avoids an array copy.
-return new String(newStr, offset, count, true);
+return new String(newStr, 0, count, true);
   }
 
   /**
@@ -1504,16 +1506,18 @@
 
 // Now we perform the conversion. Fortunately, there are no
 // multi-character lowercase expansions in Unicode 3.0.0.
-char[] newStr = (char[]) value.clone();
+char[] newStr = new char[count];
+VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
 do
   {
 char ch = value[x];
 // Hardcoded special case.
-newStr[x++] = Character.toLowerCase(ch);
+newStr[x - offset] = Character.toLowerCase(ch);
+x++;
   }
 while (--i = 0);
 // Package constructor avoids an array copy.
-return new String(newStr, offset, count, true);
+return new String(newStr, 0, count, true);
  }
   }
 
@@ -1557,22 +1561,24 @@
 i = count;
 if (expand == 0)
   {
-char[] newStr = (char[]) value.clone();
+char[] newStr = new char[count];
+VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
 while (--i = 0)
   {
 char ch = value[x];
 // Hardcoded special case.
 if (ch != '\u0069')
   {
-newStr[x++] = Character.toUpperCase(ch);
+newStr[x - offset] = Character.toUpperCase(ch);
   }
 else
   {
-newStr[x++] = '\u0130';
+newStr[x - offset] = '\u0130';
   }
+x++;
   }
 // Package constructor avoids an array copy.
-return new String(newStr, offset, count, true);
+return new String(newStr, 0, count, true);
   }
 
 // Expansion is necessary.
@@ -1642,14 +1648,16 @@
 i = count;
 if (expand == 0)
   {
-char[] newStr = (char[]) value.clone();
+char[] newStr = new char[count];
+VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset));
 while (--i = 0)
   {
 char ch = value[x];
-newStr[x++] = Character.toUpperCase(ch);
+newStr[x - offset] = Character.toUpperCase(ch

Re: [cp-patches] RFC: tweaks to java.util.zip.ZipEntry

2008-02-07 Thread Ian Rogers

Mark Wielaard wrote:

On Tue, 2008-02-05 at 06:07 -0700, Tom Tromey wrote:
  

Ian == Ian Rogers [EMAIL PROTECTED] writes:
  

Ian the attached patch stops the lazy initialization of a Calendar object
Ian in ZipEntry and instead uses a static final one.

I thought this could lead to odd results sometimes, when the
calendrical data is in a zip.  But it is hard to remember.  Maybe a
bit of archaeology is in order -- looking through the cvs logs or the
list archives to see why the code is the way it is.  (That info should
be in comments, of course...)



I don't remember all the details, but here are some pointers:
http://gcc.gnu.org/ml/java-patches/2002-q4/msg00294.html
http://gcc.gnu.org/ml/java/2003-03/msg00253.html
http://gcc.gnu.org/ml/java/2003-11/msg00105.html

Sorry for being lazy myself...

Cheers,

Mark

  
Here's a revision to my original patch that only uses the copy 
constructor in the case the class is a regular ZipEntry. As Mark pointed 
out, the normal case for a ZipEntry is that we just read it, its 
therefore only when writing out we may need to convert between the DOS 
and millisecond time representations. Having a global shared Calendar 
causes bootstrap issues, so what the patch does is just uses a locally 
created Calendar in the case we must convert from DOS to millisecond 
time or vice versa. The time value is cached so that we only take the 
hit of using Calendar once per conversion, as opposed to frequently in 
some cases before. The net result is to push up the size of a ZipEntry, 
avoid boot strap issues, possibly speed up some patterns of getting and 
setting the entry's time but take a hit in creating a Calendar instance 
when a conversion is necessary (ie potentially when writing out zip 
entries). I think this is what we probably want, but would welcome feedback.


Thanks,
Ian
Index: java/util/zip/ZipEntry.java
===
RCS file: /sources/classpath/classpath/java/util/zip/ZipEntry.java,v
retrieving revision 1.20
diff -u -r1.20 ZipEntry.java
--- java/util/zip/ZipEntry.java 7 Oct 2007 18:48:46 -   1.20
+++ java/util/zip/ZipEntry.java 7 Feb 2008 10:09:38 -
@@ -50,23 +50,39 @@
  */
 public class ZipEntry implements ZipConstants, Cloneable
 {
-  private static final int KNOWN_SIZE   = 1;
-  private static final int KNOWN_CSIZE  = 2;
-  private static final int KNOWN_CRC= 4;
-  private static final int KNOWN_TIME   = 8;
-  private static final int KNOWN_EXTRA  = 16;
-
-  private static Calendar cal;
-
-  private String name;
+  private static final byte KNOWN_SIZE= 1;
+  private static final byte KNOWN_CSIZE   = 2;
+  private static final byte KNOWN_CRC = 4;
+  private static final byte KNOWN_TIME= 8;
+  private static final byte KNOWN_DOSTIME = 16
+  private static final byte KNOWN_EXTRA   = 32;
+
+  /** Immutable name of the entry */
+  private final String name;
+  /** Uncompressed size */
   private int size;
+  /** Compressed size */
   private long compressedSize = -1;
+  /** CRC of uncompressed data */
   private int crc;
+  /** Comment or null if none */
+  private String comment = null;
+  /** The compression method. Either DEFLATED or STORED, by default -1. */
+  private byte method = -1;
+  /** Flags specifying what we know about this entry */
+  private byte known = 0;
+  /**
+   * The 32bit DOS encoded format for the time of this entry. Only valid if
+   * KNOWN_DOSTIME is set in known.
+   */
   private int dostime;
-  private short known = 0;
-  private short method = -1;
+  /**
+   * The 64bit Java encoded millisecond time since the beginning of the epoch.
+   * Only valid if KNOWN_TIME is set in known.
+   */
+  private long time;
+  /** Extra data */
   private byte[] extra = null;
-  private String comment = null;
 
   int flags;  /* used by ZipOutputStream */
   int offset; /* used by ZipFile and ZipOutputStream */
@@ -113,6 +129,7 @@
 compressedSize = e.compressedSize;
 crc = e.crc;
 dostime = e.dostime;
+time = e.time;
 method = e.method;
 extra = e.extra;
 comment = e.comment;
@@ -121,37 +138,60 @@
   final void setDOSTime(int dostime)
   {
 this.dostime = dostime;
-known |= KNOWN_TIME;
+known |= KNOWN_DOSTIME;
+known = ~KNOWN_TIME;
   }
 
   final int getDOSTime()
   {
-if ((known  KNOWN_TIME) == 0)
-  return 0;
-else
+if ((known  KNOWN_DOSTIME) != 0)
   return dostime;
+else  if ((known  KNOWN_TIME) != 0)
+  {
+   Calendar cal = Calendar.getInstance();
+   cal.setTimeInMillis(time);
+   dostime = (cal.get(Calendar.YEAR) - 1980  0x7f)  25
+  | (cal.get(Calendar.MONTH) + 1)  21
+  | (cal.get(Calendar.DAY_OF_MONTH))  16
+  | (cal.get(Calendar.HOUR_OF_DAY))  11
+  | (cal.get(Calendar.MINUTE))  5
+  | (cal.get(Calendar.SECOND))  1;
+   known |= KNOWN_DOSTIME;
+   return dostime;
+  }
+else

[cp-patches] FYI: changes of StringBuffer to StringBuilder, new Number(x) to Number.valueOf(x), add final to a few private fields and avoid creating Integer objects for the sake of comparison

2008-02-06 Thread Ian Rogers
Apologies this was committed yesterday and I should have posted the 
patch here earlier.


Ian

CVSROOT:/sources/classpath
Module name:classpath
Changes by: Ian Rogers irogers  08/02/05 14:59:06

Modified files:
gnu/java/lang/reflect: TypeSignature.java
java/io: BufferedReader.java DataInputStream.java
java/lang  : StackTraceElement.java Throwable.java
java/lang/reflect: Proxy.java
java/net   : URI.java URLClassLoader.java URLEncoder.java
java/text  : SimpleDateFormat.java
java/util  : AbstractMap.java Calendar.java Date.java
 Hashtable.java

Log message:
2008-02-05  Ian Rogers  [EMAIL PROTECTED]

* gnu/java/lang/reflect/TypeSignature.java
* java/io/BufferedReader.java
* java/io/DataInputStream.java
* java/lang/StackTraceElement.java
* java/lang/Throwable.java
* java/lang/reflect/Proxy.java
* java/net/URI.java
* java/net/URLClassLoader.java
* java/net/URLEncoder.java
* java/text/SimpleDateFormat.java
* java/util/AbstractMap.java
* java/util/Calendar.java
* java/util/Date.java
* java/util/Hashtable.java
Use StringBuilder in preference to StringBuffer
* java/util/Calendar.java
* java/util/Hashtable.java
Make private fields that can be final, final
* java/net/URI.java
Avoid creating Integer objects for the sake of comparison
* java/lang/reflect/Proxy.java
* java/text/SimpleDateFormat.java
Swap use of new Character/Integer to use of valueOf methods

Index: gnu/java/lang/reflect/TypeSignature.java
===
RCS file: 
/sources/classpath/classpath/gnu/java/lang/reflect/TypeSignature.java,v

retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- gnu/java/lang/reflect/TypeSignature.java2 Jul 2005 20:32:12 
-   1.14
+++ gnu/java/lang/reflect/TypeSignature.java5 Feb 2008 14:59:04 
-   1.15

@@ -239,7 +239,7 @@
   public static String getEncodingOfMethod(Method m)
   {
 Class[] paramTypes = m.getParameterTypes();
-StringBuffer buf = new StringBuffer().append('(');
+StringBuilder buf = new StringBuilder(();
 for (int i = 0; i  paramTypes.length; i++)
   buf.append(getEncodingOfClass(paramTypes[i].getName(), true));
 buf.append(')').append(getEncodingOfClass(m.getReturnType().getName(),
@@ -261,7 +261,7 @@
   public static String getEncodingOfConstructor(Constructor c)
   {
 Class[] paramTypes = c.getParameterTypes();
-StringBuffer buf = new StringBuffer().append('(');
+StringBuilder buf = new StringBuilder(();
 for (int i = 0; i  paramTypes.length; i++)
   buf.append(getEncodingOfClass(paramTypes[i].getName(), true));
 buf.append()V);
Index: java/io/BufferedReader.java
===
RCS file: /sources/classpath/classpath/java/io/BufferedReader.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- java/io/BufferedReader.java 2 Jul 2005 20:32:37 -   1.27
+++ java/io/BufferedReader.java 5 Feb 2008 14:59:04 -   1.28
@@ -89,11 +89,6 @@
   static final int DEFAULT_BUFFER_SIZE = 8192;

   /**
-   * The line buffer for codereadLine/code.
-   */
-  private StringBuffer sbuf = null;
-
-  /**
 * Create a new codeBufferedReader/code that will read from the
 * specified subordinate stream with a default buffer size of 8192 
chars.

 *
@@ -455,10 +450,7 @@
pos++;
return str;
   }
-if (sbuf == null)
-  sbuf = new StringBuffer(200);
-else
-  sbuf.setLength(0);
+StringBuilder sbuf = new StringBuilder(200);
 sbuf.append(buffer, pos, i - pos);
 pos = i;
 // We only want to return null when no characters were read before
Index: java/io/DataInputStream.java
===
RCS file: /sources/classpath/classpath/java/io/DataInputStream.java,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- java/io/DataInputStream.java29 Jan 2008 22:30:44 -  1.32
+++ java/io/DataInputStream.java5 Feb 2008 14:59:04 -   1.33
@@ -350,7 +350,7 @@
*/
   public final String readLine() throws IOException
   {
-StringBuffer strb = new StringBuffer();
+StringBuilder strb = new StringBuilder();

 while (true)
   {
@@ -747,7 +747,7 @@
   {
 // Give StringBuffer an initial estimated size to avoid
 // enlarge buffer frequently
-StringBuffer strbuf = new StringBuffer (buf.length / 2 + 2);
+StringBuilder strbuf

[commit-cp] classpath ChangeLog

2008-02-06 Thread Ian Rogers
CVSROOT:/sources/classpath
Module name:classpath
Changes by: Ian Rogers irogers08/02/06 19:00:46

Modified files:
.  : ChangeLog 

Log message:
Changelog missed from last commit

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/ChangeLog?cvsroot=classpathr1=1.9480r2=1.9481




Re: [cp-patches] RFC: use helper method to clone char array in java.lang.String

2008-02-05 Thread Ian Rogers

Robert Lougher wrote:

Hi,

On 2/4/08, Ian Rogers [EMAIL PROTECTED] wrote:
  

Hi,

xalan performs 1.4 million char array clones per iteration of the normal
size DaCapo benchmark. All of the character array clones are coming from
java.lang.String. The attached patch changes the use of char[].clone
(which maps to java.lang.Object.clone) to a helper method that allocates
the character array and then array copies from the source to the new
array. On the Jikes RVM I get the following performance results from 10
iterations of DaCapo using the large data set size:

current java.lang.String using char[].clone:
run 1: 99157ms
run 2: 98700ms
run 3: 97927ms

patched java.lang.String using the helper routine:
run 1: 97710ms
run 2: 97406ms
run 3: 96762ms

The speed up is between 0.22% and 1.2%. Do people think using the helper
is a sensible change?




I would like to see evidence that this is a win, or at least has no
slowdown on other VMs (i.e. it is VM independent).  I think it would
be inappropriate if it was only to address implementation issues in
JikesRVM.  For example, why is the helper faster than clone?  Surely
all clone() should be doing is an alloc and then an arraycopy?

Rob.
  


Hi Rob, Twisti, Tromey,

so what happens in the case of the clone is:

1) call into clone
2) determine that this is a clone of an array
3) create array of same length as that which we're cloning (we inline as 
far as here in the case of Jikes RVM)

4) call into array copy
5) determine type of array we're copying
6) check for overlaps
7) copy arrays
8) leave array copy and clone
9) check that the resulting array casts back to a char[]

in the case of the helper method:

1) call into helper method
2) create array of same length as that which we're cloning
3) call into array copy
4) determine type of array we're copying
5) check for overlaps
6) copy arrays (we inline as far as here in the case of Jikes RVM)
7) leave array copy and helper method

The Jikes RVM is performing a lot of partial evaluation to determine 
that a lot of bounds checks, casts, instanceof tests are unnecessary and 
the result is code that just allocates the array and performs a copy 
without checks. In the case of clone our partial evaluation breaks down 
because we need the results of runtime reflection calls or to know that 
these calls are analogous to bytecodes when the arguments are constant. 
I plan to do optimizations in this direction, but I don't want to 
flatter the optimizations when they probably only effect a small number 
of situations and alternate view is that code may have been written in a 
slightly esoteric manner.


I think the Jikes RVM is performing more optimizations than other 
Classpath VMs, so its likely the performance win will be less marked for 
those VMs (if there's any win at all). I think Tromey's point is valid 
and I'll try to write a better patch to address it. Once I have posted 
the new patch maybe we can return to the question as to whether to make 
the change.


Thanks for all the feedback!
Ian



[cp-patches] RFC: tweaks to java.util.zip.ZipEntry

2008-02-05 Thread Ian Rogers

Hi,

the attached patch stops the lazy initialization of a Calendar object in 
ZipEntry and instead uses a static final one. It also modifies the clone 
method to instead of using Object.clone to use the ZipEntry's own copy 
constructor. This patch has implications to bootstrapping and subtly 
changes ZipEntry's behavior. I welcome feedback prior to committing.


Thanks,
Ian
--- java/util/zip/ZipEntry.java 2007-10-07 19:48:46.0 +0100
+++ java/util/zip/ZipEntry.java 2008-02-05 12:32:22.0 +
@@ -56,9 +56,10 @@
   private static final int KNOWN_TIME   = 8;
   private static final int KNOWN_EXTRA  = 16;
 
-  private static Calendar cal;
+  /** Calendar used for time computations */
+  private static final Calendar cal = Calendar.getInstance();
 
-  private String name;
+  private final String name;
   private int size;
   private long compressedSize = -1;
   private int crc;
@@ -140,18 +141,13 @@
*/
   public Object clone()
   {
-try
-  {
-   // The JCL says that the `extra' field is also copied.
-   ZipEntry clone = (ZipEntry) super.clone();
-   if (extra != null)
- clone.extra = (byte[]) extra.clone();
-   return clone;
-  }
-catch (CloneNotSupportedException ex)
+ZipEntry clone = new ZipEntry(this);
+if (extra != null)
   {
-   throw new InternalError();
+   clone.extra = new byte[extra.length];
+   System.arraycopy(extra, 0, clone.extra, 0, extra.length);
   }
+return clone;
   }
 
   /**
@@ -169,7 +165,6 @@
*/
   public void setTime(long time)
   {
-Calendar cal = getCalendar();
 synchronized (cal)
   {
cal.setTimeInMillis(time);
@@ -204,7 +199,6 @@

 try
   {
-   cal = getCalendar();
synchronized (cal)
  {
cal.set(year, mon, day, hrs, min, sec);
@@ -219,14 +213,6 @@
   }
   }
 
-  private static synchronized Calendar getCalendar()
-  {
-if (cal == null)
-  cal = Calendar.getInstance();
-
-return cal;
-  }
-
   /**
* Sets the size of the uncompressed data.
* @exception IllegalArgumentException if size is not in 0..0xL


Re: [cp-patches] RFC: use helper method to clone char array in java.lang.String

2008-02-05 Thread Ian Rogers

Hello all,

here's a revised patch that removes the use of clone in preference to 
just array copying the live portion of the String. Here are the DaCapo 
xalan figures:


run 1: 97972ms
run 2: 97837ms
run 3: 95290ms

which represents anything from a 0.04% slow down to a 2.8% speed up. 
There will also be a space saving as we're not cloning whole arrays any 
more. Please let me know if you think this patch is suitable for inclusion.


Thanks,
Ian
--- java/lang/String.java   2008-01-23 09:01:02.0 +
+++ java/lang/String.java   2008-02-05 10:07:56.0 +
@@ -1303,13 +1303,13 @@
 break;
 if (i  0)
   return this;
-char[] newStr = (char[]) value.clone();
-newStr[x] = newChar;
+char[] newStr = toCharArray();
+newStr[x-offset] = newChar;
 while (--i = 0)
   if (value[++x] == oldChar)
-newStr[x] = newChar;
+newStr[x-offset] = newChar;
 // Package constructor avoids an array copy.
-return new String(newStr, offset, count, true);
+return new String(newStr, 0, count, true);
   }
 
   /**
@@ -1450,23 +1450,25 @@
 
 // Now we perform the conversion. Fortunately, there are no multi-character
 // lowercase expansions in Unicode 3.0.0.
-char[] newStr = (char[]) value.clone();
+char[] newStr = new char[count];
+VMSystem.arraycopy(value, offset, newStr, 0, count-(x-offset));
 do
   {
 char ch = value[x];
 // Hardcoded special case.
 if (ch != '\u0049')
   {
-newStr[x++] = Character.toLowerCase(ch);
+newStr[x-offset] = Character.toLowerCase(ch);
   }
 else
   {
-newStr[x++] = '\u0131';
+newStr[x-offset] = '\u0131';
   }
+x++;
   }
 while (--i = 0);
 // Package constructor avoids an array copy.
-return new String(newStr, offset, count, true);
+return new String(newStr, 0, count, true);
   }
 
   /**
@@ -1504,16 +1506,18 @@
 
 // Now we perform the conversion. Fortunately, there are no
 // multi-character lowercase expansions in Unicode 3.0.0.
-char[] newStr = (char[]) value.clone();
+char[] newStr = new char[count];
+VMSystem.arraycopy(value, offset, newStr, 0, count-(x-offset));
 do
   {
 char ch = value[x];
 // Hardcoded special case.
-newStr[x++] = Character.toLowerCase(ch);
+newStr[x-offset] = Character.toLowerCase(ch);
+x++;
   }
 while (--i = 0);
 // Package constructor avoids an array copy.
-return new String(newStr, offset, count, true);
+return new String(newStr, 0, count, true);
  }
   }
 
@@ -1557,22 +1561,24 @@
 i = count;
 if (expand == 0)
   {
-char[] newStr = (char[]) value.clone();
+char[] newStr = new char[count];
+VMSystem.arraycopy(value, offset, newStr, 0, count-(x-offset));
 while (--i = 0)
   {
 char ch = value[x];
 // Hardcoded special case.
 if (ch != '\u0069')
   {
-newStr[x++] = Character.toUpperCase(ch);
+newStr[x-offset] = Character.toUpperCase(ch);
   }
 else
   {
-newStr[x++] = '\u0130';
+newStr[x-offset] = '\u0130';
   }
+x++;
   }
 // Package constructor avoids an array copy.
-return new String(newStr, offset, count, true);
+return new String(newStr, 0, count, true);
   }
 
 // Expansion is necessary.
@@ -1642,14 +1648,16 @@
 i = count;
 if (expand == 0)
   {
-char[] newStr = (char[]) value.clone();
+char[] newStr = new char[count];
+VMSystem.arraycopy(value, offset, newStr, 0, count-(x-offset));
 while (--i = 0)
   {
 char ch = value[x];
-newStr[x++] = Character.toUpperCase(ch);
+newStr[x-offset] = Character.toUpperCase(ch);
+x++;
   }
 // Package constructor avoids an array copy.
-return new String(newStr, offset, count, true);
+return new String(newStr, 0, count, true);
   }
 
 // Expansion is necessary.
@@ -1730,9 +1738,6 @@
*/
   public char[] toCharArray()
   {
-if (count == value.length)
-  return (char[]) value.clone();
-
 char[] copy = new char[count];
 VMSystem.arraycopy(value, offset, copy, 0, count);
 return copy;


[cp-patches] RFC: use helper method to clone char array in java.lang.String

2008-02-04 Thread Ian Rogers

Hi,

xalan performs 1.4 million char array clones per iteration of the normal 
size DaCapo benchmark. All of the character array clones are coming from 
java.lang.String. The attached patch changes the use of char[].clone 
(which maps to java.lang.Object.clone) to a helper method that allocates 
the character array and then array copies from the source to the new 
array. On the Jikes RVM I get the following performance results from 10 
iterations of DaCapo using the large data set size:


current java.lang.String using char[].clone:
run 1: 99157ms
run 2: 98700ms
run 3: 97927ms

patched java.lang.String using the helper routine:
run 1: 97710ms
run 2: 97406ms
run 3: 96762ms

The speed up is between 0.22% and 1.2%. Do people think using the helper 
is a sensible change?


Thanks,
Ian
--- java/lang/String.java   2008-01-23 09:01:02.0 +
+++ java/lang/String.java   2008-02-04 13:43:02.0 +
@@ -1284,6 +1284,13 @@
 return new String(newStr, 0, newStr.length, true);
   }
 
+  private static char[] cloneCharArray(char[] src)
+  {
+char[] copy = new char[src.length];
+VMSystem.arraycopy(src, 0, copy, 0, src.length);
+return copy;  
+  }
+
   /**
* Replaces every instance of a character in this String with a new
* character. If no replacements occur, this is returned.
@@ -1303,7 +1310,7 @@
 break;
 if (i  0)
   return this;
-char[] newStr = (char[]) value.clone();
+char[] newStr = cloneCharArray(value);
 newStr[x] = newChar;
 while (--i = 0)
   if (value[++x] == oldChar)
@@ -1450,7 +1457,7 @@
 
 // Now we perform the conversion. Fortunately, there are no multi-character
 // lowercase expansions in Unicode 3.0.0.
-char[] newStr = (char[]) value.clone();
+char[] newStr = cloneCharArray(value);
 do
   {
 char ch = value[x];
@@ -1504,7 +1511,7 @@
 
 // Now we perform the conversion. Fortunately, there are no
 // multi-character lowercase expansions in Unicode 3.0.0.
-char[] newStr = (char[]) value.clone();
+char[] newStr = cloneCharArray(value);
 do
   {
 char ch = value[x];
@@ -1557,7 +1564,7 @@
 i = count;
 if (expand == 0)
   {
-char[] newStr = (char[]) value.clone();
+char[] newStr = cloneCharArray(value);
 while (--i = 0)
   {
 char ch = value[x];
@@ -1642,7 +1649,7 @@
 i = count;
 if (expand == 0)
   {
-char[] newStr = (char[]) value.clone();
+char[] newStr = cloneCharArray(value);
 while (--i = 0)
   {
 char ch = value[x];
@@ -1731,7 +1738,7 @@
   public char[] toCharArray()
   {
 if (count == value.length)
-  return (char[]) value.clone();
+  return cloneCharArray(value);
 
 char[] copy = new char[count];
 VMSystem.arraycopy(value, offset, copy, 0, count);


Re: [cp-patches] FYI: more CopyOnWriteArrayList fixlets

2007-11-26 Thread Ian Rogers

Mario Torre wrote:

I'm committing this one, that fixes a couple of woops! I did in the
last patch, as well as some other methods that were already broken
(read: not my fault :)

Now it should pass all the public domain tck166 tests, except for
subList.

Thanks,
Mario
  


This is great! The Jikes RVM has gone from passing 41 out of 56 JSR166 
TCK tests to passing 43 out of 56:


Pre-patch:
http://www.cs.man.ac.uk/~irogers/jsr166-old/
Current status:
http://www.cs.man.ac.uk/~irogers/jsr166/


Looking at the current status, TimeUnitTest looks to be failing as the 
version of JSR166 in the external directory is old enough not to be 
declaring TimeUnit.MILLISECONDS:


http://www.cs.man.ac.uk/~irogers/jsr166/production/jsr166-tck/TimeUnitTest.default-output.txt

I wonder if some of the other failures could be down to an old JSR 166. 
What's the protocol to update the code in the external directory?


Thanks,
Ian



[commit-cp] classpath AUTHORS

2007-11-24 Thread Ian Rogers
CVSROOT:/cvsroot/classpath
Module name:classpath
Changes by: Ian Rogers irogers07/11/23 14:38:58

Modified files:
.  : AUTHORS 

Log message:
add myself

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/AUTHORS?cvsroot=classpathr1=1.41r2=1.42




[commit-cp] classpath/java/lang Long.java

2007-11-24 Thread Ian Rogers
CVSROOT:/cvsroot/classpath
Module name:classpath
Changes by: Ian Rogers irogers07/11/23 14:50:53

Modified files:
java/lang  : Long.java 

Log message:
Remove unnecessary synchronized from Long.valueOf(long)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/java/lang/Long.java?cvsroot=classpathr1=1.24r2=1.25




[commit-cp] classpath/java io/FileOutputStream.java io/Prin...

2007-11-24 Thread Ian Rogers
CVSROOT:/cvsroot/classpath
Module name:classpath
Changes by: Ian Rogers irogers07/11/23 14:58:14

Modified files:
java/io: FileOutputStream.java PrintStream.java 
java/util  : Locale.java 

Log message:
Make private fields that can be final, final.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/java/io/FileOutputStream.java?cvsroot=classpathr1=1.38r2=1.39
http://cvs.savannah.gnu.org/viewcvs/classpath/java/io/PrintStream.java?cvsroot=classpathr1=1.29r2=1.30
http://cvs.savannah.gnu.org/viewcvs/classpath/java/util/Locale.java?cvsroot=classpathr1=1.39r2=1.40




[commit-cp] classpath/java/lang String.java

2007-11-24 Thread Ian Rogers
CVSROOT:/cvsroot/classpath
Module name:classpath
Changes by: Ian Rogers irogers07/11/23 15:04:25

Modified files:
java/lang  : String.java 

Log message:
Separate Turkish case conversion into their own routines. Switch from 
using String.equals to == for the language detection as Locale's language is 
interned.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/java/lang/String.java?cvsroot=classpathr1=1.86r2=1.87




[commit-cp] classpath/gnu/java/nio/charset ByteCharset.java...

2007-11-24 Thread Ian Rogers
CVSROOT:/cvsroot/classpath
Module name:classpath
Changes by: Ian Rogers irogers07/11/23 15:12:17

Modified files:
gnu/java/nio/charset: ByteCharset.java Cp424.java Cp437.java 
  Cp737.java Cp775.java Cp850.java 
  Cp852.java Cp855.java Cp857.java 
  Cp860.java Cp861.java Cp862.java 
  Cp863.java Cp864.java Cp865.java 
  Cp866.java Cp869.java Cp874.java 
  EncodingHelper.java ISO_8859_1.java 
  ISO_8859_13.java ISO_8859_15.java 
  ISO_8859_2.java ISO_8859_3.java 
  ISO_8859_4.java ISO_8859_5.java 
  ISO_8859_6.java ISO_8859_7.java 
  ISO_8859_8.java ISO_8859_9.java KOI_8.java 
  MS874.java MacCentralEurope.java 
  MacCroatian.java MacCyrillic.java 
  MacDingbat.java MacGreek.java 
  MacIceland.java MacRoman.java 
  MacRomania.java MacSymbol.java 
  MacThai.java MacTurkish.java Provider.java 
  US_ASCII.java Windows1250.java 
  Windows1251.java Windows1252.java 
  Windows1253.java Windows1254.java 
  Windows1255.java Windows1256.java 
  Windows1257.java Windows1258.java 

Log message:
Addition of array optimized encoding/decoding for byte character sets, 
US_ASCII and ISO_8859_1.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ByteCharset.java?cvsroot=classpathr1=1.6r2=1.7
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp424.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp437.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp737.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp775.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp850.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp852.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp855.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp857.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp860.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp861.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp862.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp863.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp864.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp865.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp866.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp869.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/Cp874.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/EncodingHelper.java?cvsroot=classpathr1=1.4r2=1.5
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ISO_8859_1.java?cvsroot=classpathr1=1.7r2=1.8
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ISO_8859_13.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ISO_8859_15.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ISO_8859_2.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ISO_8859_3.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ISO_8859_4.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ISO_8859_5.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ISO_8859_6.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ISO_8859_7.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ISO_8859_8.java?cvsroot=classpathr1=1.2r2=1.3
http://cvs.savannah.gnu.org/viewcvs

Re: [cp-patches] Streamline String.toUpper/LowerCase

2007-11-23 Thread Ian Rogers

Committed.

Ian Rogers wrote:

Hi,

the attached patch separates out the special case of making a string 
upper and lower case for the Turkish Locale. As Locale's language 
should be interned, the tr.equals test is replaced with tr ==.


Thanks,
Ian





Re: [cp-patches] Fix for GTk peers with Classpath 0.96.1

2007-11-23 Thread Ian Rogers

Committed.

Ian Rogers wrote:

Hi,

attached is a patch required to make JNI GTk peers work on 32bit 
architectures.


Regards,
Ian





Re: [cp-patches] Patch to gnu.java.nio.charset

2007-11-23 Thread Ian Rogers

Committed.

Ian Rogers wrote:

Hi,

the attached patch adds efficient support for array encoding/decoding 
character sets to all ByteCharsets, US_ASCII and ISO_8859_1. It does 
this by using 2 package private helper classes. The patch also makes 
fields and classes that can be final, final. The patch also adds the 
use of generic types where appropriate.


Thanks,
Ian





Re: [cp-patches] Make fields that aren't final, final

2007-11-23 Thread Ian Rogers

committed.

Ian Rogers wrote:

Hi,

the attached patch makes a few fields that could be final, final.

Thanks,
Ian





[cp-patches] FYI: java.lang.Long remove unnecessary synchronized

2007-11-23 Thread Ian Rogers

Hi,

Committed.

Regards,
Ian
Index: Long.java
===
RCS file: /cvsroot/classpath/classpath/java/lang/Long.java,v
retrieving revision 1.24
diff -u -r1.24 Long.java
--- Long.java   10 Dec 2006 20:25:44 -  1.24
+++ Long.java   23 Nov 2007 14:49:12 -
@@ -296,7 +296,7 @@
* @return the codeLong/code
* @since 1.5
*/
-  public static synchronized Long valueOf(long val)
+  public static Long valueOf(long val)
   {
 // We aren't required to cache here.  We could, though perhaps we
 // ought to consider that as an empirical question.


Re: New GNU Classpath developer Ian Rogers

2007-11-23 Thread Ian Rogers

Mark Wielaard wrote:

Hi all,

I am happy to announce that Ian is now one of our active hackers with
commit access. Ian has been pushing useful patches for a long time now
and is one of the JikesRVM hackers.

Ian, even though you have been contributing to GNU Classpath in the
past you name is missing in the AUTHORS file. Please post a patch and
ChangeLog entry to add yourself to the AUTHORS file to the
classpath-patches mailinglist. You can consider that patch pre-approved
so feel free to commit it immediately as a test of your new powers. But
remember that with power comes responsibility! (*)

Thanks,

Mark

(*) http://www.gnu.org/software/classpath/docs/hacking.html
  


Hi Mark and everyone,

thanks for the welcome. I've used my powers and added myself to the 
AUTHORS list.


Thanks again,
Ian



[commit-cp] classpath/gnu/java/nio/charset ByteEncodeLoopHe...

2007-11-23 Thread Ian Rogers
CVSROOT:/sources/classpath
Module name:classpath
Changes by: Ian Rogers irogers07/11/23 16:11:17

Added files:
gnu/java/nio/charset: ByteEncodeLoopHelper.java 
  ByteDecodeLoopHelper.java 

Log message:
Helper classes for array optimized byte character set encoding/decoding

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ByteEncodeLoopHelper.java?cvsroot=classpathrev=1.1
http://cvs.savannah.gnu.org/viewcvs/classpath/gnu/java/nio/charset/ByteDecodeLoopHelper.java?cvsroot=classpathrev=1.1




[commit-cp] classpath ChangeLog

2007-11-23 Thread Ian Rogers
CVSROOT:/sources/classpath
Module name:classpath
Changes by: Ian Rogers irogers07/11/23 17:06:57

Modified files:
.  : ChangeLog 

Log message:
2007-11-23  Ian Rogers  [EMAIL PROTECTED]

* java/io/FileOutputStream.java,
* java/io/PrintStream.java,
* java/util/Locale.java:
Make fields that can be final, final.
* gnu/java/nio/charset/ByteCharset.java,
* gnu/java/nio/charset/Cp424.java,
* gnu/java/nio/charset/Cp437.java,
* gnu/java/nio/charset/Cp737.java,
* gnu/java/nio/charset/Cp775.java,
* gnu/java/nio/charset/Cp850.java,
* gnu/java/nio/charset/Cp852.java,
* gnu/java/nio/charset/Cp855.java,
* gnu/java/nio/charset/Cp857.java,
* gnu/java/nio/charset/Cp860.java,
* gnu/java/nio/charset/Cp861.java,
* gnu/java/nio/charset/Cp862.java,
* gnu/java/nio/charset/Cp863.java,
* gnu/java/nio/charset/Cp864.java,
* gnu/java/nio/charset/Cp865.java,
* gnu/java/nio/charset/Cp866.java,
* gnu/java/nio/charset/Cp869.java,
* gnu/java/nio/charset/Cp874.java,
* gnu/java/nio/charset/EncodingHelper.java,
* gnu/java/nio/charset/ISO_8859_13.java,
* gnu/java/nio/charset/ISO_8859_15.java,
* gnu/java/nio/charset/ISO_8859_1.java,
* gnu/java/nio/charset/ISO_8859_2.java,
* gnu/java/nio/charset/ISO_8859_3.java,
* gnu/java/nio/charset/ISO_8859_4.java,
* gnu/java/nio/charset/ISO_8859_5.java,
* gnu/java/nio/charset/ISO_8859_6.java,
* gnu/java/nio/charset/ISO_8859_7.java,
* gnu/java/nio/charset/ISO_8859_8.java,
* gnu/java/nio/charset/ISO_8859_9.java,
* gnu/java/nio/charset/KOI_8.java,
* gnu/java/nio/charset/MacCentralEurope.java,
* gnu/java/nio/charset/MacCroatian.java,
* gnu/java/nio/charset/MacCyrillic.java,
* gnu/java/nio/charset/MacDingbat.java,
* gnu/java/nio/charset/MacGreek.java,
* gnu/java/nio/charset/MacIceland.java,
* gnu/java/nio/charset/MacRomania.java,
* gnu/java/nio/charset/MacRoman.java,
* gnu/java/nio/charset/MacSymbol.java,
* gnu/java/nio/charset/MacThai.java,
* gnu/java/nio/charset/MacTurkish.java,
* gnu/java/nio/charset/MS874.java,
* gnu/java/nio/charset/Provider.java,
* gnu/java/nio/charset/US_ASCII.java,
* gnu/java/nio/charset/Windows1250.java,
* gnu/java/nio/charset/Windows1251.java,
* gnu/java/nio/charset/Windows1252.java,
* gnu/java/nio/charset/Windows1253.java,
* gnu/java/nio/charset/Windows1254.java,
* gnu/java/nio/charset/Windows1255.java,
* gnu/java/nio/charset/Windows1256.java,
* gnu/java/nio/charset/Windows1257.java,
* gnu/java/nio/charset/Windows1258.java,
* gnu/java/nio/charset/ByteDecodeLoopHelper.java,
* gnu/java/nio/charset/ByteEncodeLoopHelper.java:
Optimize for array based buffers.
* native/jni/gtk-peer/gtkpeer.c:
Make 32bit pointer a global JNI reference.
* java/lang/String:
(toLowerCaseTurkish): new method.
(toUpperCaseTurkish): new method.
(toLowerCase): special case Turkish
(toUpperCase): likewise.
* java/lang/Long:
(valueOf): remove unnecessary synchronized.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/ChangeLog?cvsroot=classpathr1=1.9436r2=1.9437




[cp-patches] Greater use of StringBuilder rather than StringBuffer

2007-10-20 Thread Ian Rogers

Hi,

the attached patch increases the use of StringBuilder in Classpath 
rather than StringBuffer.


Thanks,
Ian
Index: gnu/java/lang/reflect/TypeSignature.java
===
RCS file: 
/sources/classpath/classpath/gnu/java/lang/reflect/TypeSignature.java,v
retrieving revision 1.14
diff -u -r1.14 TypeSignature.java
--- gnu/java/lang/reflect/TypeSignature.java2 Jul 2005 20:32:12 -   
1.14
+++ gnu/java/lang/reflect/TypeSignature.java20 Oct 2007 11:10:50 -
@@ -239,7 +239,7 @@
   public static String getEncodingOfMethod(Method m)
   {
 Class[] paramTypes = m.getParameterTypes();
-StringBuffer buf = new StringBuffer().append('(');
+StringBuilder buf = new StringBuilder(();
 for (int i = 0; i  paramTypes.length; i++)
   buf.append(getEncodingOfClass(paramTypes[i].getName(), true));
 buf.append(')').append(getEncodingOfClass(m.getReturnType().getName(),
@@ -261,7 +261,7 @@
   public static String getEncodingOfConstructor(Constructor c)
   {
 Class[] paramTypes = c.getParameterTypes();
-StringBuffer buf = new StringBuffer().append('(');
+StringBuilder buf = new StringBuilder(();
 for (int i = 0; i  paramTypes.length; i++)
   buf.append(getEncodingOfClass(paramTypes[i].getName(), true));
 buf.append()V);
Index: java/io/BufferedReader.java
===
RCS file: /sources/classpath/classpath/java/io/BufferedReader.java,v
retrieving revision 1.27
diff -u -r1.27 BufferedReader.java
--- java/io/BufferedReader.java 2 Jul 2005 20:32:37 -   1.27
+++ java/io/BufferedReader.java 20 Oct 2007 11:10:50 -
@@ -89,11 +89,6 @@
   static final int DEFAULT_BUFFER_SIZE = 8192;
 
   /**
-   * The line buffer for codereadLine/code.
-   */
-  private StringBuffer sbuf = null;
-
-  /**
 * Create a new codeBufferedReader/code that will read from the 
 * specified subordinate stream with a default buffer size of 8192 chars.
 *
@@ -455,10 +450,7 @@
pos++;
return str;
   }
-if (sbuf == null)
-  sbuf = new StringBuffer(200);
-else
-  sbuf.setLength(0);
+StringBuilder sbuf = new StringBuilder(200);
 sbuf.append(buffer, pos, i - pos);
 pos = i;
 // We only want to return null when no characters were read before
Index: java/io/DataInputStream.java
===
RCS file: /sources/classpath/classpath/java/io/DataInputStream.java,v
retrieving revision 1.31
diff -u -r1.31 DataInputStream.java
--- java/io/DataInputStream.java2 Jul 2005 20:32:37 -   1.31
+++ java/io/DataInputStream.java20 Oct 2007 11:10:50 -
@@ -349,7 +349,7 @@
*/
   public final String readLine() throws IOException
   {
-StringBuffer strb = new StringBuffer();
+StringBuilder strb = new StringBuilder();
 
 while (true)
   {
@@ -703,7 +703,7 @@
   {
 // Give StringBuffer an initial estimated size to avoid 
 // enlarge buffer frequently
-StringBuffer strbuf = new StringBuffer (buf.length / 2 + 2);
+StringBuilder strbuf = new StringBuilder (buf.length / 2 + 2);
 
 for (int i = 0; i  buf.length; )
   {
Index: java/lang/StackTraceElement.java
===
RCS file: /sources/classpath/classpath/java/lang/StackTraceElement.java,v
retrieving revision 1.9
diff -u -r1.9 StackTraceElement.java
--- java/lang/StackTraceElement.java8 Apr 2006 11:02:12 -   1.9
+++ java/lang/StackTraceElement.java20 Oct 2007 11:10:50 -
@@ -202,7 +202,7 @@
*/
   public String toString()
   {
-StringBuffer sb = new StringBuffer();
+StringBuilder sb = new StringBuilder();
 if (declaringClass != null)
   {
 sb.append(declaringClass);
Index: java/lang/Throwable.java
===
RCS file: /sources/classpath/classpath/java/lang/Throwable.java,v
retrieving revision 1.30
diff -u -r1.30 Throwable.java
--- java/lang/Throwable.java2 Jul 2005 20:32:39 -   1.30
+++ java/lang/Throwable.java20 Oct 2007 11:10:50 -
@@ -411,7 +411,7 @@
   // different threads to get mixed up when written to the same PrintWriter.
   private String stackTraceString()
   {
-StringBuffer sb = new StringBuffer();
+StringBuilder sb = new StringBuilder();
 
 // Main stacktrace
 StackTraceElement[] stack = getStackTrace();
@@ -455,7 +455,7 @@
 
   // Adds to the given StringBuffer a line containing the name and
   // all stacktrace elements minus the last equal ones.
-  private static void stackTraceStringBuffer(StringBuffer sb, String name,
+  private static void stackTraceStringBuffer(StringBuilder sb, String name,
StackTraceElement[] stack, int equal)
   {
 String nl = StaticData.nl;
Index: java/lang/reflect/Proxy.java

[cp-patches] Greater use of Number.valueOf rather than new Number

2007-10-20 Thread Ian Rogers

Hi,

the attached patch increases the use of Number.valueOf  rather than 
new Number.


Thanks,
Ian
Index: java/beans/PropertyChangeSupport.java
===
RCS file: /sources/classpath/classpath/java/beans/PropertyChangeSupport.java,v
retrieving revision 1.15
diff -u -r1.15 PropertyChangeSupport.java
--- java/beans/PropertyChangeSupport.java   12 Feb 2006 13:53:54 -  
1.15
+++ java/beans/PropertyChangeSupport.java   20 Oct 2007 11:16:49 -
@@ -346,8 +346,8 @@
   {
 if (oldVal != newVal)
   firePropertyChange(new PropertyChangeEvent(source, propertyName,
- new Integer(oldVal),
- new Integer(newVal)));
+ Integer.valueOf(oldVal),
+ Integer.valueOf(newVal)));
   }
 
   /**
Index: java/beans/VetoableChangeSupport.java
===
RCS file: /sources/classpath/classpath/java/beans/VetoableChangeSupport.java,v
retrieving revision 1.13
diff -u -r1.13 VetoableChangeSupport.java
--- java/beans/VetoableChangeSupport.java   28 Jun 2006 14:13:40 -  
1.13
+++ java/beans/VetoableChangeSupport.java   20 Oct 2007 11:16:49 -
@@ -349,8 +349,8 @@
   {
 if (oldVal != newVal)
   fireVetoableChange(new PropertyChangeEvent(source, propertyName,
- new Integer(oldVal),
- new Integer(newVal)));
+ Integer.valueOf(oldVal),
+ Integer.valueOf(newVal)));
   }
 
   /**
Index: java/io/ObjectStreamClass.java
===
RCS file: /sources/classpath/classpath/java/io/ObjectStreamClass.java,v
retrieving revision 1.49
diff -u -r1.49 ObjectStreamClass.java
--- java/io/ObjectStreamClass.java  21 Jun 2007 06:19:27 -  1.49
+++ java/io/ObjectStreamClass.java  20 Oct 2007 11:16:49 -
@@ -812,7 +812,7 @@
   }
 
 if (loadedByBootOrApplicationClassLoader(cl))
-  uidCache.put(cl,new Long(result));
+  uidCache.put(cl,Long.valueOf(result));
   }
 return result;
   }
Index: java/lang/reflect/Array.java
===
RCS file: /sources/classpath/classpath/java/lang/reflect/Array.java,v
retrieving revision 1.17
diff -u -r1.17 Array.java
--- java/lang/reflect/Array.java21 Jun 2007 05:39:50 -  1.17
+++ java/lang/reflect/Array.java20 Oct 2007 11:16:49 -
@@ -209,19 +209,19 @@
 if (array instanceof boolean[])
   return ((boolean[]) array)[index] ? Boolean.TRUE : Boolean.FALSE;
 if (array instanceof byte[])
-  return new Byte(((byte[]) array)[index]);
+  return Byte.valueOf(((byte[]) array)[index]);
 if (array instanceof char[])
-  return new Character(((char[]) array)[index]);
+  return Character.valueOf(((char[]) array)[index]);
 if (array instanceof short[])
-  return new Short(((short[]) array)[index]);
+  return Short.valueOf(((short[]) array)[index]);
 if (array instanceof int[])
-  return new Integer(((int[]) array)[index]);
+  return Integer.valueOf(((int[]) array)[index]);
 if (array instanceof long[])
-  return new Long(((long[]) array)[index]);
+  return Long.valueOf(((long[]) array)[index]);
 if (array instanceof float[])
-  return new Float(((float[]) array)[index]);
+  return Float.valueOf(((float[]) array)[index]);
 if (array instanceof double[])
-  return new Double(((double[]) array)[index]);
+  return Double.valueOf(((double[]) array)[index]);
 if (array == null)
   throw new NullPointerException();
 throw new IllegalArgumentException();
Index: java/net/DatagramSocket.java
===
RCS file: /sources/classpath/classpath/java/net/DatagramSocket.java,v
retrieving revision 1.50
diff -u -r1.50 DatagramSocket.java
--- java/net/DatagramSocket.java17 Nov 2006 15:09:05 -  1.50
+++ java/net/DatagramSocket.java20 Oct 2007 11:16:49 -
@@ -403,7 +403,7 @@
 if (timeout  0)
   throw new IllegalArgumentException(Invalid timeout:  + timeout);
 
-getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
+getImpl().setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
   }
 
   /**
@@ -450,7 +450,7 @@
 if (size  0)
   throw new IllegalArgumentException(Buffer size is less than 0);
 
-getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
+getImpl().setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(size));
   }
 
   /**
@@ -497,7 +497,7 @@
 if (size  0)
   throw new 

[cp-patches] Make fields that aren't final, final

2007-10-20 Thread Ian Rogers

Hi,

the attached patch makes a few fields that could be final, final.

Thanks,
Ian
Index: java/io/FileOutputStream.java
===
RCS file: /sources/classpath/classpath/java/io/FileOutputStream.java,v
retrieving revision 1.38
diff -u -r1.38 FileOutputStream.java
--- java/io/FileOutputStream.java   17 Sep 2006 07:31:42 -  1.38
+++ java/io/FileOutputStream.java   20 Oct 2007 11:21:59 -
@@ -59,7 +59,7 @@
 {
   private FileDescriptor fd;
 
-  private FileChannelImpl ch;
+  private final FileChannelImpl ch;
 
   /**
* This method initializes a codeFileOutputStream/code object to write
Index: java/io/PrintStream.java
===
RCS file: /sources/classpath/classpath/java/io/PrintStream.java,v
retrieving revision 1.29
diff -u -r1.29 PrintStream.java
--- java/io/PrintStream.java10 Dec 2006 20:25:44 -  1.29
+++ java/io/PrintStream.java20 Oct 2007 11:21:59 -
@@ -76,7 +76,7 @@
   /**
*  Encoding name
*/
-  private String encoding;
+  private final String encoding;
 
   /**
* This boolean indicates whether or not an error has ever occurred
@@ -88,7 +88,7 @@
* This is codetrue/code if auto-flush is enabled, 
* codefalse/code otherwise
*/
-  private boolean auto_flush;
+  private final boolean auto_flush;
 
   /**
* This method initializes a new codePrintStream/code object to write
@@ -185,16 +185,17 @@
   public PrintStream (OutputStream out, boolean auto_flush)
   {
 super (out);
-
+String encoding;
 try {
-   this.encoding = SystemProperties.getProperty(file.encoding);
+   encoding = SystemProperties.getProperty(file.encoding);
 } catch (SecurityException e){
-   this.encoding = ISO8859_1;
+   encoding = ISO8859_1;
 } catch (IllegalArgumentException e){
-   this.encoding = ISO8859_1;
+   encoding = ISO8859_1;
 } catch (NullPointerException e){
-   this.encoding = ISO8859_1;
+   encoding = ISO8859_1;
 }
+this.encoding = encoding;
 this.auto_flush = auto_flush;
   }
 
Index: java/util/Locale.java
===
RCS file: /sources/classpath/classpath/java/util/Locale.java,v
retrieving revision 1.38
diff -u -r1.38 Locale.java
--- java/util/Locale.java   2 Jan 2007 21:40:20 -   1.38
+++ java/util/Locale.java   20 Oct 2007 11:21:59 -
@@ -178,21 +178,21 @@
*
* @serial the languange, possibly 
*/
-  private String language;
+  private final String language;
 
   /**
* The country code, as returned by getCountry().
*
* @serial the country, possibly 
*/
-  private String country;
+  private final String country;
 
   /**
* The variant code, as returned by getVariant().
*
* @serial the variant, possibly 
*/
-  private String variant;
+  private final String variant;
 
   /**
* This is the cached hashcode. When writing to stream, we write -1.
@@ -324,13 +324,12 @@
 // default locale.
 if (defaultLocale != null)
   {
-language = convertLanguage(language).intern();
-country = country.toUpperCase().intern();
-variant = variant.intern();
-  }
-this.language = language;
-this.country = country;
-this.variant = variant;
+language = convertLanguage(language);
+country = country.toUpperCase();
+  }
+this.language = language.intern();
+this.country = country.intern();
+this.variant = variant.intern();
 hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode();
   }
 
@@ -1022,9 +1021,6 @@
 throws IOException, ClassNotFoundException
   {
 s.defaultReadObject();
-language = language.intern();
-country = country.intern();
-variant = variant.intern();
 hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode();
   }
 } // class Locale


[cp-patches] Streamline String.toUpper/LowerCase

2007-10-20 Thread Ian Rogers

Hi,

the attached patch separates out the special case of making a string 
upper and lower case for the Turkish Locale. As Locale's language should 
be interned, the tr.equals test is replaced with tr ==.


Thanks,
Ian
Index: java/lang/String.java
===
RCS file: /sources/classpath/classpath/java/lang/String.java,v
retrieving revision 1.86
diff -u -r1.86 String.java
--- java/lang/String.java   2 Jan 2007 00:51:01 -   1.86
+++ java/lang/String.java   20 Oct 2007 11:44:55 -
@@ -1431,27 +1431,18 @@
   }
 
   /**
-   * Lowercases this String according to a particular locale. This uses
-   * Unicode's special case mappings, as applied to the given Locale, so the
-   * resulting string may be a different length.
-   *
-   * @param loc locale to use
-   * @return new lowercased String, or this if no characters were lowercased
-   * @throws NullPointerException if loc is null
-   * @see #toUpperCase(Locale)
-   * @since 1.1
+   * Convert string to lower case for a Turkish locale that requires special
+   * handling of '\u0049'
*/
-  public String toLowerCase(Locale loc)
+  private String toLowerCaseTurkish()
   {
 // First, see if the current string is already lower case.
-boolean turkish = tr.equals(loc.getLanguage());
 int i = count;
 int x = offset - 1;
 while (--i = 0)
   {
 char ch = value[++x];
-if ((turkish  ch == '\u0049')
-|| ch != Character.toLowerCase(ch))
+if ((ch == '\u0049') || ch != Character.toLowerCase(ch))
   break;
   }
 if (i  0)
@@ -1464,8 +1455,14 @@
   {
 char ch = value[x];
 // Hardcoded special case.
-newStr[x++] = (turkish  ch == '\u0049') ? '\u0131'
-  : Character.toLowerCase(ch);
+if (ch != '\u0049')
+  {
+newStr[x++] = Character.toLowerCase(ch);
+  }
+else
+  {
+newStr[x++] = '\u0131';
+  }
   }
 while (--i = 0);
 // Package constructor avoids an array copy.
@@ -1473,6 +1470,54 @@
   }
 
   /**
+   * Lowercases this String according to a particular locale. This uses
+   * Unicode's special case mappings, as applied to the given Locale, so the
+   * resulting string may be a different length.
+   *
+   * @param loc locale to use
+   * @return new lowercased String, or this if no characters were lowercased
+   * @throws NullPointerException if loc is null
+   * @see #toUpperCase(Locale)
+   * @since 1.1
+   */
+  public String toLowerCase(Locale loc)
+  {
+// First, see if the current string is already lower case.
+
+// Is loc turkish? String equality test is ok as Locale.language is 
interned
+if (tr == loc.getLanguage())
+  {
+return toLowerCaseTurkish();
+  }
+else
+  {
+int i = count;
+int x = offset - 1;
+while (--i = 0)
+  {
+char ch = value[++x];
+if (ch != Character.toLowerCase(ch))
+  break;
+  }
+if (i  0)
+  return this;
+
+// Now we perform the conversion. Fortunately, there are no
+// multi-character lowercase expansions in Unicode 3.0.0.
+char[] newStr = (char[]) value.clone();
+do
+  {
+char ch = value[x];
+// Hardcoded special case.
+newStr[x++] = Character.toLowerCase(ch);
+  }
+while (--i = 0);
+// Package constructor avoids an array copy.
+return new String(newStr, offset, count, true);
+ }
+  }
+
+  /**
* Lowercases this String. This uses Unicode's special case mappings, as
* applied to the platform's default Locale, so the resulting string may
* be a different length.
@@ -1487,21 +1532,12 @@
   }
 
   /**
-   * Uppercases this String according to a particular locale. This uses
-   * Unicode's special case mappings, as applied to the given Locale, so the
-   * resulting string may be a different length.
-   *
-   * @param loc locale to use
-   * @return new uppercased String, or this if no characters were uppercased
-   * @throws NullPointerException if loc is null
-   * @see #toLowerCase(Locale)
-   * @since 1.1
+   * Uppercase this string for a Turkish locale
*/
-  public String toUpperCase(Locale loc)
+  private String toUpperCaseTurkish()
   {
 // First, see how many characters we have to grow by, as well as if the
 // current string is already upper case.
-boolean turkish = tr.equals(loc.getLanguage());
 int expand = 0;
 boolean unchanged = true;
 int i = count;
@@ -1511,7 +1547,7 @@
 char ch = value[--x];
 expand += upperCaseExpansion(ch);
 unchanged = (unchanged  expand == 0
-  ! (turkish  ch == '\u0069')
+  ch != '\u0069'
   ch == Character.toUpperCase(ch));
   }
 if (unchanged)
@@ -1526,8 +1562,14 @@
   {
   

[cp-patches] Patch to java.io.OutputStreamWriter

2007-10-19 Thread Ian Rogers

Hi,

the attached patch makes fields of OutputStreamWriter that can be final, 
final.


Thanks,
Ian
--- java/io/OutputStreamWriter.java 2007-10-12 13:01:47.0 +0100
+++ java/io/OutputStreamWriter.java 2007-10-19 15:46:37.0 +0100
@@ -91,17 +91,17 @@
   /**
* The charset encoder.
*/
-  private CharsetEncoder encoder;
+  private final CharsetEncoder encoder;
 
   /**
* java.io canonical name of the encoding.
*/
-  private String encodingName;
+  private final String encodingName;
 
   /**
* Buffer output before character conversion as it has costly overhead.
*/
-  private CharBuffer outputBuffer;
+  private final CharBuffer outputBuffer;
   private final static int BUFFER_SIZE = 1024;
 
   /**
@@ -120,8 +120,10 @@
   public OutputStreamWriter (OutputStream out, String encoding_scheme) 
 throws UnsupportedEncodingException
   {
+CharsetEncoder encoder;
+String encodingName;
 this.out = out;
-   outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
+outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
 
 try 
   {
@@ -130,42 +132,44 @@
  {
encodingName = ISO8859_1;
encoder = null;
-   return;
  }
-
-   /*
-* Workaround for encodings with a byte-order-mark.
-* We only want to write it once per stream.
-*/
-   try 
- {
-   if(encoding_scheme.equalsIgnoreCase(UnicodeBig) || 
-  encoding_scheme.equalsIgnoreCase(UTF-16) ||
-  encoding_scheme.equalsIgnoreCase(UTF16))
+   else
+  {
+   /*
+* Workaround for encodings with a byte-order-mark.
+* We only want to write it once per stream.
+*/
+try 
+  {
+   if(encoding_scheme.equalsIgnoreCase(UnicodeBig) || 
+encoding_scheme.equalsIgnoreCase(UTF-16) ||
+encoding_scheme.equalsIgnoreCase(UTF16))
+ {
+   encoding_scheme = UTF-16BE; 
+out.write((byte)0xFE);
+out.write((byte)0xFF);
+  } 
+   else if(encoding_scheme.equalsIgnoreCase(UnicodeLittle))
+  {
+   encoding_scheme = UTF-16LE;
+   out.write((byte)0xFF);
+   out.write((byte)0xFE);
+ }
+ }
+   catch(IOException ioe)
  {
-   encoding_scheme = UTF-16BE; 
-   out.write((byte)0xFE);
-   out.write((byte)0xFF);
- } 
-   else if(encoding_scheme.equalsIgnoreCase(UnicodeLittle)){
- encoding_scheme = UTF-16LE;
- out.write((byte)0xFF);
- out.write((byte)0xFE);
-   }
- }
-   catch(IOException ioe)
- {
- }
+ }
   
-   Charset cs = EncodingHelper.getCharset(encoding_scheme);
-   if(cs == null)
- throw new UnsupportedEncodingException(Encoding +encoding_scheme+
- unknown);
-   encoder = cs.newEncoder();
-   encodingName = EncodingHelper.getOldCanonical(cs.name());
-
-   encoder.onMalformedInput(CodingErrorAction.REPLACE);
-   encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+   Charset cs = EncodingHelper.getCharset(encoding_scheme);
+   if(cs == null)
+ throw new UnsupportedEncodingException(Encoding 
+encoding_scheme+
+ unknown);
+encoder = cs.newEncoder();
+   encodingName = EncodingHelper.getOldCanonical(cs.name());
+
+   encoder.onMalformedInput(CodingErrorAction.REPLACE);
+   encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+  }
   } 
 catch(RuntimeException e) 
   {
@@ -174,6 +178,8 @@
encoder = null; 
encodingName = ISO8859_1;
   }
+this.encoder = encoder;
+this.encodingName = encodingName;
   }
 
   /**
@@ -184,8 +190,10 @@
*/
   public OutputStreamWriter (OutputStream out)
   {
+CharsetEncoder encoder;
+String encodingName;
 this.out = out;
-   outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
+outputBuffer = CharBuffer.allocate(BUFFER_SIZE);
 try 
   {
String encoding = System.getProperty(file.encoding);
@@ -204,6 +212,8 @@
encoder.onMalformedInput(CodingErrorAction.REPLACE);
encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
   }
+this.encoder = encoder;
+this.encodingName = encodingName;
   }
 
   /**


[cp-patches] Fix for GTk peers with Classpath 0.96.1

2007-10-17 Thread Ian Rogers

Hi,

attached is a patch required to make JNI GTk peers work on 32bit 
architectures.


Regards,
Ian
--- native/jni/gtk-peer/gtkpeer.c   2007-05-08 01:00:54.0 +0100
+++ native/jni/gtk-peer/gtkpeer.c   2007-10-17 10:49:25.0 +0100
@@ -102,11 +102,13 @@
 #else
 #if SIZEOF_VOID_P == 4
   pointerClass = (*env)-FindClass(env, gnu/classpath/Pointer32);
-  pointerDataFID = (*env)-GetFieldID(env, pointerClass, data, I);
-
-  /* Find the Pointer32 constructor. */
-  pointerConstructorMID = (*env)-GetMethodID(env, pointerClass, init,
-  (I)V);
+  if (pointerClass != NULL)
+{
+  pointerClass = (*env)-NewGlobalRef (env, pointerClass);
+  pointerDataFID = (*env)-GetFieldID (env, pointerClass, data, I);
+  pointerConstructorMID = (*env)-GetMethodID (env, pointerClass, init,
+   (I)V);
+}
 #else
 #error Pointer size is not supported.
 #endif /* SIZEOF_VOID_P == 4 */


[cp-patches] Fix for GTk peers and portable native sync

2007-09-27 Thread Ian Rogers

Hi,

this patch removes a call to atexit from GtkToolkit. The comment didn't 
give sufficient detail as to why the atexit call was necessary and the 
failure I witnessed in the Jikes RVM was as follows:


1) VM runs some AWT code that causes the atexit routine in GtkToolkit to 
be registered

2) VM shuts down, stopping all of its services (GC...)
3) VM calls exit that calls atexit routines
4) gdk_threads_enter is called via atexit, this then calls JNI monitor 
enter in the shutdown VM


the shutdown VM can't handle the JNI call and locks up. There is an 
assumption in the Jikes RVM that atexit routines won't exist that call 
JNI functions.


Thanks,
Ian
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c  2007-04-04 
12:30:32.0 +0100
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c  2007-09-27 
13:48:41.0 +0100
@@ -182,10 +182,6 @@
 
   gtk_widget_set_default_colormap (gdk_rgb_get_colormap ());
 
-  /* Make sure queued calls don't get sent to GTK/GDK while 
- we're shutting down. */
-  atexit (gdk_threads_enter);
-
   if ((homedir = getenv (HOME)))
 {
   rcpath = (char *) g_malloc (strlen (homedir) + strlen (RC_FILE) + 2);


Re: [Jikesrvm-core] [cp-patches] Changes to ThreadLocal

2007-08-23 Thread Ian Rogers

Hi,

here is a revision of Daniel's patch, from Daniel, that revises a bug 
with InheritableThreadLocals not calling childValue. This bug was found 
through the JSR 166 TCK, which now passes its thread local tests.


Thanks,
Ian

Daniel Frampton wrote:

In order to tease out where the performance differences were coming
from, I implemented a map specialized for thread locals
(ThreadLocalMap.java) and found that the performance is essentially the
same as the version Ian posted earlier that stores ThreadLocal data in a
per-thread direct indexed array.

Steve ran the numbers for first and third iteration performance (-1 and
-3).

http://cs.anu.edu.au/people/Steve.Blackburn/jikesrvm/vole-2007-08-22-Wed
-213259-1.txt
http://cs.anu.edu.au/people/Steve.Blackburn/jikesrvm/vole-2007-08-22-Wed
-213259-3.txt

All numbers are from JikesRVM and listed from left to right are the
original (WeakIdentityHashMap) the array version suggested by Ian, and
the ThreadLocalMap version.

The implementation is essentially a map of weak references to values
that are lazily cleaned up as the map is manipulated. I think this is a
good balance of performance and design, but I am open to suggestions. To
allow other VMs to benefit from this I have made all these changes
within classpath (patch attached).

The job still remains to improve the WeakIdentityHashMap so it does not
perform allocation as it searches the buckets in the fast case for a
simple get(), but I believe that optimizing the ThreadLocal case is
worthwhile regardless as in some benchmarks they are performance
critical.

Thanks  Regards,
Daniel Frampton.

  
--- java/lang/Thread.java   2006-12-11 10:06:55.0 +1100
+++ java/lang/Thread.java   2007-08-22 19:20:32.0 +1000
@@ -159,7 +159,7 @@
   /** Thread local storage. Package accessible for use by
 * InheritableThreadLocal.
 */
-  WeakIdentityHashMap locals;
+  final ThreadLocalMap locals;
 
   /** The uncaught exception handler.  */
   UncaughtExceptionHandler exceptionHandler;
@@ -367,6 +367,7 @@
 this.name = name.toString();
 this.runnable = target;
 this.stacksize = size;
+this.locals = new ThreadLocalMap();
 
 synchronized (Thread.class)
   {
@@ -398,6 +399,7 @@
*/
   Thread(VMThread vmThread, String name, int priority, boolean daemon)
   {
+this.locals = new ThreadLocalMap();
 this.vmThread = vmThread;
 this.runnable = null;
 if (name == null)
@@ -1063,21 +1065,15 @@
   {
 group.removeThread(this);
 vmThread = null;
-locals = null;
+locals.clear();
   }
 
   /**
* Returns the map used by ThreadLocal to store the thread local values.
*/
-  static Map getThreadLocals()
+  static ThreadLocalMap getThreadLocals()
   {
-Thread thread = currentThread();
-Map locals = thread.locals;
-if (locals == null)
-  {
-locals = thread.locals = new WeakIdentityHashMap();
-  }
-return locals;
+return currentThread().locals;
   }
 
   /** 
--- java/lang/ThreadLocal.java  2006-12-11 07:25:44.0 +1100
+++ java/lang/ThreadLocal.java  2007-08-22 18:45:24.0 +1000
@@ -37,9 +37,6 @@
 
 package java.lang;
 
-import java.util.Map;
-
-
 /**
  * ThreadLocal objects have a different state associated with every
  * Thread that accesses them. Every access to the ThreadLocal object
@@ -93,13 +90,31 @@
* user. Do not expose this to the public. Package visible for use by
* InheritableThreadLocal
*/
-  static final Object sentinel = new Object();
+  static final Object notFound = new Object();
+
+  /**
+   * The base for the computation of the next hash for a thread local.
+   */
+  private static int nextHashBase = 1;
+
+  /**
+   * Allocate a new hash.
+   */
+  private synchronized int computeNextHash() {
+return nextHashBase++ * 6709;
+  }
+
+  /**
+   * Hash code computed for ThreadLocalMap
+   */
+  final int fastHash;
 
   /**
* Creates a ThreadLocal object without associating any value to it yet.
*/
   public ThreadLocal()
   {
+fastHash = computeNextHash();
   }
 
   /**
@@ -125,16 +140,16 @@
*/
   public T get()
   {
-MapThreadLocalT,T map = (MapThreadLocalT,T) 
Thread.getThreadLocals();
+ThreadLocalMap map = Thread.getThreadLocals();
 // Note that we don't have to synchronize, as only this thread will
 // ever modify the map.
-T value = map.get(this);
-if (value == null)
+T value = (T) map.get(this);
+if (value == notFound)
   {
 value = initialValue();
-map.put(this, (T) (value == null ? sentinel : value));
+map.set(this, value);
   }
-return value == (T) sentinel ? null : value;
+return value;
   }
 
   /**
@@ -147,10 +162,10 @@
*/
   public void set(T value)
   {
-Map map = Thread.getThreadLocals();
+ThreadLocalMap map = Thread.getThreadLocals();
 // Note that we don't have to synchronize, as only this thread will
 // ever modify the map.
-map.put(this, value == 

Re: [cp-patches] Changes to ThreadLocal

2007-08-22 Thread Ian Rogers

Jeroen Frijters wrote:

No, any VM that implements the spec is vulnerable. Here's an example of a 
possible attack:

class Attacker
{
  static ArrayListThreadLocal resurrected;
  ArrayListThreadLocal list = new ArrayListThreadLocal();

  Attacker()
  {
for (int i = 0; i  1000; i++)
{
  list.add(new ThreadLocal());
}
  }

  protected void finalize()
  {
resurrected = list;
  }

  static void attack()
  {
new Attacker();
System.gc();
System.runFinalization();
runSomeHighTrustCodeThatWillAllocateThreadLocal();
for (ThreadLocal t : resurrected)
{
   if (t.get() != null)
   {
  System.out.println(We've stolen the object: + t.get());
   }
}
  }
}

I hope this clarifies the problem with finalizers. A PhantomReference doesn't 
suffer from this problem, because it only gets enqueued after the object 
*really* is gone. For another example of this bug in GNU Classpath see 
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29499
  


Thanks Jeroen, it's clear now. The problem with a phantom reference is 
that when we collect the thread local we should also really make 
collectable all of the values set to thread locals. A phantom reference 
won't do this and so introduces a memory leak until something can run 
over the queue of phantom references freeing all the allocated thread 
local slots. As you say, we can use phantom references, wouldn't another 
way be to implement say our own system weak reference, with a guarantee 
there are no references and weak references to the object? Having a 
thread that polls a normally empty queue seems undesirable both for this 
and Classpath bug 29499.


Thanks again,
Ian



Re: [cp-patches] Changes to ThreadLocal

2007-08-21 Thread Ian Rogers

Jeroen Frijters wrote:

Ian Rogers wrote:
  

the attached patch modifies ThreadLocal to use an array of Objects hung
off Thread rather than a weak hash map hung off Thread. On DaCapo's
Jython benchmark this can improve the performance of the Jikes RVM by
more than 10%. It also improves other DaCapo benchmark performance. GCJ
already has a similar mechanism to use pthread thread locals.



This patch looks wrong to me:

1) Values are strongly reachable, which means they potentially won't be garbage 
collected.
2) Value slots are reused without clearing them, which means potential security 
hole.

Regards,
Jeroen

  

Thanks Jeroen,

you're of course right. Without reinventing extra indirections in the 
locals it strikes me that the easiest way to solve these problems is 
with a finalizer (groan) in the thread local that iterates over every 
thread reverting the slot location to the sentinel value. I'll test and 
revise the patch.


Regards,
Ian



Re: [cp-patches] Changes to ThreadLocal

2007-08-21 Thread Ian Rogers

Andrew Haley wrote:

Ian Rogers writes:
  Jeroen Frijters wrote:
   Ian Rogers wrote:
 
   the attached patch modifies ThreadLocal to use an array of Objects hung

   off Thread rather than a weak hash map hung off Thread. On DaCapo's
   Jython benchmark this can improve the performance of the Jikes RVM by
   more than 10%. It also improves other DaCapo benchmark performance. GCJ
   already has a similar mechanism to use pthread thread locals.
   
  

   This patch looks wrong to me:
  
   1) Values are strongly reachable, which means they potentially won't be 
garbage collected.
   2) Value slots are reused without clearing them, which means potential 
security hole.
  
  you're of course right. Without reinventing extra indirections in the 
  locals it strikes me that the easiest way to solve these problems is 
  with a finalizer (groan) in the thread local that iterates over every 
  thread reverting the slot location to the sentinel value. I'll test and 
  revise the patch.


In the gcj pthreads version I keep the WeakIdentityHashMap but I have
a look-aside cache that's used by get().  set() is slow by get() is
fast.  Like this:

java::lang::ThreadLocal::get (void)
{
  if (TLSPointer == NULL)
return internalGet ();   // Slow version, creates the ThreadLocal and 
updates the HashMap

  tls_t* tls = (tls_t*)TLSPointer;
  void *obj = pthread_getspecific(tls-key);  // A fast lookup in an area of 
memory the garbage collector doesn't scan.

  if (obj)
return (::java::lang::Object *)obj;

  ::java::lang::Object *value = internalGet ();  // Slow version again.

Garbage collection isn't affected because the use of the HashMap is
exactly the same as in the previous Classpath version, and the gc
doesn't scan the pthreads memory area used for thread locals.  This
gets the fast path (the usual case) down to a few instructions.  I
suppose it's only really an advantage on VMs with very low overhead
native calls.

Andrew.
  

Hi all,

here is the revised patch. The get and set methods are deliberately 
about as short as they can be, they are very very hot in benchmarks and 
need to be tight, ie read/write the variable and catch cases where the 
thread local data structure isn't set up yet via a bound check failure. 
When a thread local is garbage collected a finalizer object runs over 
every thread making sure we free up the thread local storage and then 
mark the local as being available again. The use of weak references that 
must be atomically nulled and not sharing locals avoids a lot of 
synchronization.


I believe the only inefficiency of this code compared to the old code is 
that the amount of local storage can't shrink as thread locals become 
unreachable in memory unless new threads are created, and there's a 
possible issue of fragmentation (similar as to would exist in the hash 
maps backing store). I think the patch makes a sensible compromise in 
ignoring this to boost the performance of get and set. For the Jikes RVM 
on DaCapo's Jython benchmark (large size for 3 iterations) the time 
taken changes from ~62 seconds to just under 51 seconds.


The use of a finalizer object is due to not wanting to over ride the 
finalize method on thread local, because of potential complications. One 
bug in the current implementation is that if the thread local overrides 
hashcode and/or equal it can be made to collide with other thread locals.


I think the revised code would also make a good revision for GCJ. It's 
possible that avoiding the use of pthread calls will boost efficiency, 
but if not it would provide a more efficient place to look on cache misses.


Thanks,
Ian
diff -u java/lang/InheritableThreadLocal.java 
java/lang/InheritableThreadLocal.java
--- java/lang/InheritableThreadLocal.java   2007-08-21 12:01:24.0 
+0100
+++ java/lang/InheritableThreadLocal.java   2007-08-21 11:55:49.0 
+0100
@@ -37,9 +37,9 @@
 
 package java.lang;
 
-import gnu.java.util.WeakIdentityHashMap;
-
-import java.util.Iterator;
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Arrays;
 
 /**
  * A ThreadLocal whose value is inherited by child Threads. The value of the
@@ -56,12 +56,22 @@
  * @author Eric Blake ([EMAIL PROTECTED])
  * @author Tom Tromey ([EMAIL PROTECTED])
  * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @author Ian Rogers ([EMAIL PROTECTED])
  * @see ThreadLocal
  * @since 1.2
  * @status updated to 1.4
  */
 public class InheritableThreadLocalT extends ThreadLocalT
 {
+  
+
+  /**
+   * Map of owners of local index to inheritable thread local. Weak references
+   * allow thread locals to be collected when no longer in use.
+   */
+  private static final 
HashMapInteger,WeakReferenceInheritableThreadLocal?
+  owners = new HashMapInteger,WeakReferenceInheritableThreadLocal?();
+  
 
   /**
* Creates a new InheritableThreadLocal that has no values associated
@@ -69,6 +79,8 @@
*/
   public InheritableThreadLocal()
   {
+super

Re: [cp-patches] Changes to ThreadLocal

2007-08-21 Thread Ian Rogers

Jeroen Frijters wrote:

Ian Rogers wrote:
  

here is the revised patch.



+  int arraySize = group.activeCount();
+  Thread[] threadList = new Thread[arraySize];
+  int filled = group.enumerate(threadList);
+  while (filled == arraySize)
+  {
+arraySize *= 2;
+threadList = new Thread[arraySize];
+filled = group.enumerate(threadList);
+  }

Shouldn't the initial array be arraySize + 1, to avoid always having to 
enumerate twice?
  


This code is taken from Thread.getAllStackTraces so the problem should 
effect both.



A bigger problem is that the ThreadLocal can be resurrected after the finalizer 
has run, so you need to either make localIndex in ThreadLocal volatile and set 
it to -1 in the finalizer, or use a PhantomReference and a ReferenceQueue to do 
the clean up.
  


How can then the thread local be resurrected after the finalizer is run? 
All the references in ThreadLocal and InheritableThreadLocal are weak 
and will be atomically cleared prior to the finalizer being run. All 
other references must be dead for the finalizer to have been run. The 
finalizer doesn't use the ThreadLocal it just clears all references to 
the slot it used to reference prior to saying that slot can be reused.


Given that thread locals normally only die when the VM shuts down or  by 
class unloading, its quite tempting just to ignore the situation of 
reclaiming their storage - its certainly a much smaller problem than the 
performance of get and set.


Thanks,
Ian



Re: [cp-patches] Changes to ThreadLocal

2007-08-21 Thread Ian Rogers

Jeroen Frijters wrote:

This is not true. Once an object becomes finalizer reachable the finalizer 
can run, but that doesn't mean all references are gone. Any object with a finalizer can 
still have references to objects that have already been finalized. In its finalizer it 
will be able to resurrect these objects. This is a well known attack vector and the 
reason that PhantomReferences were introduced to do post-mortem cleanup.
  


In normal use it would be so hard to do this, but you're right that in 
theory someone could try to use a thread local after its been finalized 
in their own finalizer using the finalizer I wrote. I've changed the 
patch as you suggested to make the localIndex an invalid value after 
finalization to prevent this attack. It's unfortunate as the change 
stops localIndex being a prime candidate for final field chasing or 
caching in a register. This seems better than using a phantom reference 
and polling a queue though.



Thanks,
Ian
diff -u java/lang/InheritableThreadLocal.java 
java/lang/InheritableThreadLocal.java
--- java/lang/InheritableThreadLocal.java   2007-08-21 12:01:24.0 
+0100
+++ java/lang/InheritableThreadLocal.java   2007-08-21 11:55:49.0 
+0100
@@ -37,9 +37,9 @@
 
 package java.lang;
 
-import gnu.java.util.WeakIdentityHashMap;
-
-import java.util.Iterator;
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Arrays;
 
 /**
  * A ThreadLocal whose value is inherited by child Threads. The value of the
@@ -56,12 +56,22 @@
  * @author Eric Blake ([EMAIL PROTECTED])
  * @author Tom Tromey ([EMAIL PROTECTED])
  * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @author Ian Rogers ([EMAIL PROTECTED])
  * @see ThreadLocal
  * @since 1.2
  * @status updated to 1.4
  */
 public class InheritableThreadLocalT extends ThreadLocalT
 {
+  
+
+  /**
+   * Map of owners of local index to inheritable thread local. Weak references
+   * allow thread locals to be collected when no longer in use.
+   */
+  private static final 
HashMapInteger,WeakReferenceInheritableThreadLocal?
+  owners = new HashMapInteger,WeakReferenceInheritableThreadLocal?();
+  
 
   /**
* Creates a new InheritableThreadLocal that has no values associated
@@ -69,6 +79,8 @@
*/
   public InheritableThreadLocal()
   {
+super();
+owners.put(localIndex, new WeakReferenceInheritableThreadLocal?(this));
   }
 
   /**
@@ -97,24 +109,25 @@
   {
 // The currentThread is the parent of the new thread.
 Thread parentThread = Thread.currentThread();
-if (parentThread.locals != null)
-  {
-Iterator keys = parentThread.locals.keySet().iterator();
-while (keys.hasNext())
-  {
-Object key = keys.next();
-if (key instanceof InheritableThreadLocal)
-  {
-   InheritableThreadLocal local = (InheritableThreadLocal)key;
-Object parentValue = parentThread.locals.get(key);
-   Object childValue = local.childValue(parentValue == sentinel
-   ? null : parentValue);
-if (childThread.locals == null)
-childThread.locals = new WeakIdentityHashMap();
-childThread.locals.put(key, (childValue == null
- ? sentinel : childValue));
-  }
+if (parentThread.locals != null) {
+  childThread.locals = new Object[parentThread.locals.length];
+  Arrays.fill(childThread.locals, sentinel);
+  for (int i=0; i  parentThread.locals.length; i++) {
+WeakReference ref = owners.get(i);
+if (ref != null) {
+  InheritableThreadLocal local = (InheritableThreadLocal)ref.get();
+  if (local != null) {
+Object parentValue = parentThread.locals[i];
+Object childValue;
+if (parentValue == sentinel) {
+  childValue = sentinel;
+} else {
+  childValue = local.childValue(parentValue);
+}
+childThread.locals[i] = childValue; 
   }
+}
   }
+}
   }
 }
diff -u java/lang/Thread.java java/lang/Thread.java
--- java/lang/Thread.java   2007-08-21 12:01:24.0 +0100
+++ java/lang/Thread.java   2007-08-21 11:55:14.0 +0100
@@ -39,14 +39,11 @@
 package java.lang;
 
 import gnu.classpath.VMStackWalker;
-import gnu.java.util.WeakIdentityHashMap;
 
 import java.lang.management.ManagementFactory;
 import java.lang.management.ThreadInfo;
 import java.lang.management.ThreadMXBean;
-
 import java.security.Permission;
-
 import java.util.HashMap;
 import java.util.Map;
 
@@ -90,6 +87,7 @@
  * @author John Keiser
  * @author Eric Blake ([EMAIL PROTECTED])
  * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @author Ian Rogers ([EMAIL PROTECTED])
  * @see Runnable
  * @see Runtime#exit(int)
  * @see #run()
@@ -156,10 +154,11 @@
   /** The default exception handler

Re: [cp-patches] Changes to ThreadLocal

2007-08-21 Thread Ian Rogers

Ian Rogers wrote:

Jeroen Frijters wrote:
This is not true. Once an object becomes finalizer reachable the 
finalizer can run, but that doesn't mean all references are gone. Any 
object with a finalizer can still have references to objects that 
have already been finalized. In its finalizer it will be able to 
resurrect these objects. This is a well known attack vector and the 
reason that PhantomReferences were introduced to do post-mortem cleanup.
  


In normal use it would be so hard to do this, but you're right that in 
theory someone could try to use a thread local after its been 
finalized in their own finalizer using the finalizer I wrote. I've 
changed the patch as you suggested to make the localIndex an invalid 
value after finalization to prevent this attack. It's unfortunate as 
the change stops localIndex being a prime candidate for final field 
chasing or caching in a register. This seems better than using a 
phantom reference and polling a queue though.


The more I think about this the less happy I am about the solution to 
not make the local index final. What my hope had been was that the 
locals would be something amenable to caching in a register for a 
thread. The local index as a final would also be amenable to constant 
propagation and access to a thread local would, in the best case, be an 
indexed register load away. The problem with escaping references, in 
this situation, doesn't effect the Jikes RVM. This is because all weak 
references that become finalizable are queued onto the finalizer thread. 
A thread local queued on the finalizer thread would only be able to look 
at the thread local variables of the finalizer thread. So the scenario 
of a secret thread running then an untrusted thread running and 
stealing data from the secret via the thread local can't occur. The 
secret thread would have to put data into the finalizer thread's 
thread local for the untrusted thread then to steal; I can't see how 
this can occur without the secret thread being complicit in trying to 
leak data to the untrusted thread - if the secret thread is being 
complicit with the untrusted thread then aren't all bets off?


Anyway, this design decision seems to hang off how weak references are 
finalized. If they are finalized on their own finalizer thread then the 
final local index design is fine and preferable imo to the volatile 
design or a weak identity hash map (however cached or stream lined) - I 
think an indexed register load is the shortest bit of code you could 
produce for this. If finalizable objects are finalized as part of 
tearing down threads then a leak is possible and for correctness the 
volatile should be used. So this comes down to a question of how 
Classpath using VMs are finalizing objects? One simple idea is to palm 
off the implementation decision to the VMThread and make the reference 
implementation use a volatile - this way the Jikes RVM, I believe, can 
get its optimal code sequence. Currently the whole issue of caching 
these values in registers for the Jikes RVM is a mute one as 
optimizations to reduce redundant loads are disabled.


Thanks,
Ian



[cp-patches] Changes to ThreadLocal

2007-08-20 Thread Ian Rogers

Hi,

the attached patch modifies ThreadLocal to use an array of Objects hung 
off Thread rather than a weak hash map hung off Thread. On DaCapo's 
Jython benchmark this can improve the performance of the Jikes RVM by 
more than 10%. It also improves other DaCapo benchmark performance. GCJ 
already has a similar mechanism to use pthread thread locals.


Regards,
Ian
diff -u java/lang/InheritableThreadLocal.java 
java/lang/InheritableThreadLocal.java
--- java/lang/InheritableThreadLocal.java   2006-12-10 20:25:44.0 
+
+++ java/lang/InheritableThreadLocal.java   2007-08-20 16:41:23.0 
+0100
@@ -37,9 +37,7 @@
 
 package java.lang;
 
-import gnu.java.util.WeakIdentityHashMap;
-
-import java.util.Iterator;
+import java.util.Arrays;
 
 /**
  * A ThreadLocal whose value is inherited by child Threads. The value of the
@@ -56,6 +54,7 @@
  * @author Eric Blake ([EMAIL PROTECTED])
  * @author Tom Tromey ([EMAIL PROTECTED])
  * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @author Ian Rogers ([EMAIL PROTECTED])
  * @see ThreadLocal
  * @since 1.2
  * @status updated to 1.4
@@ -93,29 +92,28 @@
* @param childThread the newly created thread, to inherit from this thread
* @see Thread#Thread(ThreadGroup, Runnable, String)
*/
-  static void newChildThread(Thread childThread)
+  static T void newChildThread(Thread childThread)
   {
 // The currentThread is the parent of the new thread.
 Thread parentThread = Thread.currentThread();
-if (parentThread.locals != null)
-  {
-Iterator keys = parentThread.locals.keySet().iterator();
-while (keys.hasNext())
-  {
-Object key = keys.next();
-if (key instanceof InheritableThreadLocal)
-  {
-   InheritableThreadLocal local = (InheritableThreadLocal)key;
-Object parentValue = parentThread.locals.get(key);
-   Object childValue = local.childValue(parentValue == sentinel
-   ? null : parentValue);
-if (childThread.locals == null)
-childThread.locals = new WeakIdentityHashMap();
-childThread.locals.put(key, (childValue == null
- ? sentinel : childValue));
-  }
+if (parentThread.locals != null) {
+  childThread.locals = new Object[parentThread.locals.length];
+  Arrays.fill(childThread.locals, sentinel);
+  for (int i=0; i  parentThread.locals.length; i++) {
+ThreadLocal? tl = owners.get(i).get();
+if (tl != null  tl instanceof InheritableThreadLocal) {
+  InheritableThreadLocal local = (InheritableThreadLocal)tl;
+  Object parentValue = parentThread.locals[i];
+  Object childValue;
+  if (parentValue == sentinel) {
+childValue = sentinel;
+  } else {
+childValue = local.childValue(parentValue);
   }
+  childThread.locals[i] = childValue; 
+}
   }
+}
   }
 }

diff -u java/lang/Thread.java java/lang/Thread.java
--- java/lang/Thread.java   2006-12-10 23:06:55.0 +
+++ java/lang/Thread.java   2007-08-20 16:59:52.0 +0100
@@ -39,14 +39,11 @@
 package java.lang;
 
 import gnu.classpath.VMStackWalker;
-import gnu.java.util.WeakIdentityHashMap;
 
 import java.lang.management.ManagementFactory;
 import java.lang.management.ThreadInfo;
 import java.lang.management.ThreadMXBean;
-
 import java.security.Permission;
-
 import java.util.HashMap;
 import java.util.Map;
 
@@ -90,6 +87,7 @@
  * @author John Keiser
  * @author Eric Blake ([EMAIL PROTECTED])
  * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @author Ian Rogers ([EMAIL PROTECTED])
  * @see Runnable
  * @see Runtime#exit(int)
  * @see #run()
@@ -156,10 +154,11 @@
   /** The default exception handler.  */
   private static UncaughtExceptionHandler defaultHandler;
 
-  /** Thread local storage. Package accessible for use by
-* InheritableThreadLocal.
-*/
-  WeakIdentityHashMap locals;
+  /** Default value for a thread with no locals. */
+  private static final Object[] noLocals = new Object[0];
+
+  /** Where thread local storage is hung by ThreadLocal. */
+  Object[] locals = noLocals;
 
   /** The uncaught exception handler.  */
   UncaughtExceptionHandler exceptionHandler;
@@ -1066,20 +1065,6 @@
 locals = null;
   }
 
-  /**
-   * Returns the map used by ThreadLocal to store the thread local values.
-   */
-  static Map getThreadLocals()
-  {
-Thread thread = currentThread();
-Map locals = thread.locals;
-if (locals == null)
-  {
-locals = thread.locals = new WeakIdentityHashMap();
-  }
-return locals;
-  }
-
   /** 
* Assigns the given codeUncaughtExceptionHandler/code to this
* thread.  This will then be called if the thread terminates due
diff -u java/lang/ThreadLocal.java java/lang/ThreadLocal.java
--- java/lang

Re: [cp-patches] Float/Double compare

2007-07-03 Thread Ian Rogers
Here's a revised version of the patch following suggestions from Andrew 
Haley.


Ian
--- java/lang/Float.java2006-12-10 15:25:44.0 -0500
+++ java/lang/Float.java2007-07-02 12:17:29.0 -0400
@@ -596,16 +596,25 @@
*/
   public static int compare(float x, float y)
   {
-if (isNaN(x))
-  return isNaN(y) ? 0 : 1;
-if (isNaN(y))
-  return -1;
-// recall that 0.0 == -0.0, so we convert to infinities and try again
-if (x == 0  y == 0)
-  return (int) (1 / x - 1 / y);
-if (x == y)
-  return 0;
+  // handle the easy cases:
+  if (x  y)
+ return -1;
+  if (x  y)
+ return 1;
 
-return x  y ? 1 : -1;
+  // handle equality respecting that 0.0 != -0.0 (hence not using x == y):
+  int ix = floatToRawIntBits(x);
+  int iy = floatToRawIntBits(y);
+  if (ix == iy)
+ return 0;
+
+  // handle NaNs:
+  if (x != x)
+ return (y != y) ? 0 : 1;
+  else if (y != y)
+ return -1;
+
+  // handle +/- 0.0
+  return (ix  iy) ? -1 : 1;
   }
 }
--- java/lang/Double.java   2006-12-10 15:25:44.0 -0500
+++ java/lang/Double.java   2007-07-02 12:18:36.0 -0400
@@ -587,16 +587,25 @@
*/
   public static int compare(double x, double y)
   {
-if (isNaN(x))
-  return isNaN(y) ? 0 : 1;
-if (isNaN(y))
-  return -1;
-// recall that 0.0 == -0.0, so we convert to infinites and try again
-if (x == 0  y == 0)
-  return (int) (1 / x - 1 / y);
-if (x == y)
-  return 0;
+  // handle the easy cases:
+  if (x  y)
+ return -1;
+  if (x  y)
+ return 1;
 
-return x  y ? 1 : -1;
+  // handle equality respecting that 0.0 != -0.0 (hence not using x == y):
+  long lx = doubleToRawLongBits(x);
+  long ly = doubleToRawLongBits(y);
+  if (lx == ly)
+ return 0;
+
+  // handle NaNs:
+  if (x != x)
+ return (y != y) ? 0 : 1;
+  else if (y != y)
+ return -1;
+
+  // handle +/- 0.0
+  return (lx  ly) ? -1 : 1;
   }
 }


Re: Float/Double compare

2007-07-02 Thread Ian Rogers

Andrew Haley wrote:

We know that any calculation involving NaN returns false, right?  So,
simple cases can be done first without the (possibly expensive) move
out of the FPU:

if (x  y)
  return -1; 
if (x  y)

  return 1;

then you can do the doubleToLongBits:

   long lx = doubleAsLongBits(x);
   long ly = doubleAsLongBits(y);

   if (lx == ly)
 return 0;

At this point we know they're unequal.  Also, either one of them is
NaN, or one of them is -0 and the other +0.  Java's doubleToLongBits
alwayse uses the canonical NaN, so we know that they can't both be
NaN.

   if (lx  ly)  
 return -1;


   return 1;
  

Hi Andrew,

this is great. I'd forgotten about the NaN test buried in 
doubleToLongBits, and I like the logic to push the  and  tests to the 
top. Using these insights I've tried to figure if there's a better way 
than this and I just wonder whether as the long bits conversions do a 
NaN test is the following cheaper:


// handle the easy cases:
   if (x  y)
   return -1;
   if (x  y)
   return 1;

// handle equality respecting that 0.0 != -0.0 (hence not using x == y):
   int ix = floatToRawIntBits(x);
   int iy = floatToRawIntBits(y);
   if (ix == iy)
   return 0;

// handle NaNs:
   if (x != x)
   return (y != y) ? 0 : 1;
   else if (y != y)
   return -1;

// handle +/- 0.0
   return (ix  iy) ? -1 : 1;

Although its almost certain a VM can do better with a VM specific 
implementation. For example, on Intel you can reuse the fact that a 
floating point compare gives you unordered information (in fact in many 
cases you need to test for this anyway). I imagine GCC is better at 
doing this kind of machine specific optimization than most JITs are.


Regards,
Ian



Re: Float/Double compare

2007-07-01 Thread Ian Rogers

Hi Mark,

Mark Wielaard wrote:

Hi Ian,

On Sat, 2007-06-30 at 15:25 -0400, Ian Rogers wrote:
  

public static int compare(float x, float y)
{
   int ix = floatAsIntBits(x);
   int iy = floatAsIntBits(y);
   if (ix == iy) return 0;
   if (isNaN(x)) return 1;
   if (isNaN(y)) return -1;
   int ix_sign = ix31;
   int iy_sign = iy31;
   if (ix_sign == iy_sign) {
 return x  y ? 1 : -1;
   } else {
 return ix_sign - iy_sign;
   }
}



I am not really comfortable with writing this as is since unless the
compiler is smart you will do a multiple isNaN() and floatToIntBits()
calls even if not necessary. Could we try to do something smarter and
factor some of this out like:

// First check for NaNs
if (x != x || y != y)
  {
int ix = floatToIntBits(x);
int iy = floatToIntBits(y);
if (ix == iy)
  return 0;
if (x != x)
  return 1;
if (y != y)
  return -1;
  }
else
  {
// Normal cases, or positive/negative zeros
if (x  y)
  return 1;
if (y  x)
  return -1;

// Either equal or positive/negative zeros
if (x == 0  y == 0)
  {
int ix = floatToIntBits(x);
int iy = floatToIntBits(y);
int ix_sign = ix  31;
int iy_sign = iy  31;
return ix_sign - iy_sign;
  }

return 0;
  }

But maybe I am not giving the compiler/jit enough credit for actually
producing such an optimized version in the first place. And this isn't
actually the same as your code since I moved the NaN checks first again.
The above assumes the NaN test (x != x) is relatively cheap since NaN is
a canonical value is java. That might be a wrong assumption. You might
be able to do something more clever with the actual ordering of floats
according to  (since if any argument is NaN or both are zero it
evaluates to false) or with the ordering of floatToIntBits, but my head
was spinning trying to keep all the corner cases right (this calls for
expanding the Mauve Float.compareTo() test).
  
Thanks for the feedback. I think your code may well be better. I think 
its good to have identified that there is at least an ~8% potential 
speed up on IA32 with my code, and potentially better with yours. There 
is of course a big dependence on what values are being compared and on 
the architecture. For the arrays of floats I'm seeing in the Jikes RVM a 
lot of the values are identical (either 0.0 or 1.0). With your code that 
has a path of 6 compares to get through. With mine its just one compare, 
but because a floating point compare of 0.0 and -0.0 will yield that 
they are identical I'm forced into doing it on their int bit 
representation to keep the 0.0 case sane.


Here's my hand wavy costing of the now 3 ways we have a doing things:

Case: x == y neither are NaN or 0.0
Newer Cost: 5 float compares
New Cost: 2 float as ints, 1 int compare
Old Cost: 5 float compares

Case: x  y and different sign
Newer Cost: 4 float compares
New Cost: 2 float as ints, 2 int compares, 2 float compares, 2 shifts, 
one subtract

Old Cost: 6 float compares

Case: x  y and same sign
Newer Cost: 4 float compares
New Cost: 2 float as ints, 2 int compares, 3 float compares, 2 shifts
Old Cost: 6 float compares

Case: x is NaN
Newer Cost: 2 float compares (I think you could reuse the original code 
which is slightly cheaper than yours)

New Cost: 2 float as ints, 1 int compare, 1 float compare
Old Cost: 2 float compares

Case: y is NaN
Newer Cost: 2 float compares (again assuming reuse of the original code)
New Cost: 2 float as ints, 1 int compare, 2 float compares
Old Cost: 2 float compares

Case: x == 0.0 and y == 0.0
Newer Cost: 2 float as ints, 6 float compares, 2 shifts, one subtract
New Cost: either 2 float as ints, 1 int compare or 2 float as ints, 2 
int compares, 2 float compares, 2 shifts, one subtract
Old Cost: 4 float compares, 2 float divides, 1 float subtract, 1 float 
to int



So I think the cases where the different ways win out are: most values 
are / then the newer way has the shortest path, most values are == 
then the new way has the shortest path, for two zeros (common in Jikes 
RVM :-( ) the new way wins out, and no one really cares about NaNs :-)


I agree about the desirable properties of your code, and I think they 
also address Pinski's concern, that floatToIntBits on the common path 
seems bad. I also agree that its good to have a short  and  path. 
Possibly the only redeeming feature of the new code was that it made == 
cheap (depending on the floatToIntBits cost). So my variant of your code 
would be:


// First check for NaNs
if (x != x) {
 if (y != y) return 0;
 else return 1;
}
else if (y != y) {
 return -1;
}
else
 {
   // Normal cases, or positive/negative zeros
   if (x  y)
 return 1;
   if (y  x)
 return -1;

   // Either equal or positive/negative zeros
   if (x == 0  y == 0)
 {
   int ix = floatToIntBits(x);
   int iy = floatToIntBits(y);
   int ix_sign = ix  31;
   int iy_sign = iy  31;
   return ix_sign

[cp-patches] Float/Double compare

2007-06-30 Thread Ian Rogers
Attached is a patch that improves the performance of an Float/Double 
compare by exploiting information carried in their bit integer/long 
versions sign bit. It removes one comparison from the normal path, as 
well as making other compares with ints/longs. When sorting an array of 
floats this can yield a little under a 8% speed up on a Pentium 4. 
There's a thread discussing whether this is a good or bad idea on the 
main mailing list, but so far I'm merrily talking to myself :-)


Ian
--- java/lang/Double.java   2006-12-10 20:25:44.0 +
+++ java/lang/Double.java   2007-06-30 22:21:39.98610 +0100
@@ -587,16 +587,17 @@
*/
   public static int compare(double x, double y)
   {
-if (isNaN(x))
-  return isNaN(y) ? 0 : 1;
-if (isNaN(y))
-  return -1;
-// recall that 0.0 == -0.0, so we convert to infinites and try again
-if (x == 0  y == 0)
-  return (int) (1 / x - 1 / y);
-if (x == y)
-  return 0;
-
-return x  y ? 1 : -1;
+long lx = doubleToLongBits(x);
+long ly = doubleToLongBits(y);
+if (lx == ly) return 0;
+if (isNaN(x)) return 1;
+if (isNaN(y)) return -1;
+int lx_sign = (int)(lx63);
+int ly_sign = (int)(ly63);
+if (lx_sign == ly_sign) {
+  return x  y ? 1 : -1;
+} else {
+  return lx_sign - ly_sign;
+}
   }
 }
--- java/lang/Float.java2006-12-10 20:25:44.0 +
+++ java/lang/Float.java2007-06-30 22:10:46.099648000 +0100
@@ -596,16 +596,17 @@
*/
   public static int compare(float x, float y)
   {
-if (isNaN(x))
-  return isNaN(y) ? 0 : 1;
-if (isNaN(y))
-  return -1;
-// recall that 0.0 == -0.0, so we convert to infinities and try again
-if (x == 0  y == 0)
-  return (int) (1 / x - 1 / y);
-if (x == y)
-  return 0;
-
-return x  y ? 1 : -1;
+int ix = floatToIntBits(x);
+int iy = floatToIntBits(y);
+if (ix == iy) return 0;
+if (isNaN(x)) return 1;
+if (isNaN(y)) return -1;
+int ix_sign = ix31;
+int iy_sign = iy31;
+if (ix_sign == iy_sign) {
+  return x  y ? 1 : -1;
+} else {
+  return ix_sign - iy_sign;
+}
   }
 }


Re: [cp-patches] Float/Double compare

2007-06-30 Thread Ian Rogers

Andrew Pinski wrote:

On 6/30/07, Ian Rogers [EMAIL PROTECTED] wrote:

Attached is a patch that improves the performance of an Float/Double
compare by exploiting information carried in their bit integer/long
versions sign bit. It removes one comparison from the normal path, as
well as making other compares with ints/longs. When sorting an array of
floats this can yield a little under a 8% speed up on a Pentium 4.
There's a thread discussing whether this is a good or bad idea on the
main mailing list, but so far I'm merrily talking to myself :-)


This is going to slow down this function for PowerPC (except for
Power6+) where you have to take a huge hit to transfer between
register sets via the stack.  For an example on the Cell, this is
going to be an extra 40-100 cycle hit.
I guess there are a lot of factors to do with the underlying 
architecture. My feeling is that we should move the code to 
VMFloat/VMDouble and then the VM can choose the appropriate version. 
Having the regular version optimized for Intel would make sense to me. 
Its not straight forward for me to benchmark the code on non-IA32 
architectures, in particular Cell. I'll try to do a Jikes RVM benchmark 
on a PowerPC I have access to in the week. My feeling is that the 
performance may not be as bad as you imagine, but it's hard to predict - 
and this may not be an architecture you care about anyway.


Regards,
Ian



Float/Double compare

2007-06-30 Thread Ian Rogers

Hi everyone,

I was tracking a bug and came across the code in Float.compare which is 
very similar to Double.compare. It just so happened that the bug was 
being caused by sorting arrays containing lots of floating point 0s. 
This occurs quite frequently in the Jikes RVM when we have an array of 
branch profile data. So the current code looks like:


public static int compare(float x, float y)
  {
if (isNaN(x))
  return isNaN(y) ? 0 : 1;
   if (isNaN(y))
  return -1;
// recall that 0.0 == -0.0, so we convert to infinities and try again
if (x == 0  y == 0)
  return (int) (1 / x - 1 / y);
if (x == y)
  return 0;
return x  y ? 1 : -1;
  }


When comparing 0 with 0 we do two NaN tests, two tests with 0, two 
floating point divides, floating point subtract and a float to int. An 
alternate way of coding the case of (x == 0  y == 0) would be:


if (x == 0  y == 0)
  return (floatAsIntBits(x)31) - (floatAsIntBits(y)  31)

The shift basically turns the ints being subtracted into 0 or -1, 0 in 
the case the value is +ve and -1 when it's negative. This changes the 
cost of 2 float divides, float subtract and float to int, into a cost of 
2 float as ints, 2 int shifts, 1 int subtract. On x86 the float to int 
is expensive (set and restore control bits yadda yadda), where as a 
float as int is just a float store and then int load. I think the latter 
pattern could be quite a lot cheaper.


In any case, it seems that this code is quite performance important and 
possibly the VM could do some clever optimizations. I wonder if it 
wouldn't be better to move compare into VMFloat and VMDouble?


Regards,
Ian



Re: Float/Double compare

2007-06-30 Thread Ian Rogers

Ian Rogers wrote:

public static int compare(float x, float y)
  {
if (isNaN(x))
  return isNaN(y) ? 0 : 1;
   if (isNaN(y))
  return -1;
// recall that 0.0 == -0.0, so we convert to infinities and try again
if (x == 0  y == 0)
  return (int) (1 / x - 1 / y);
if (x == y)
  return 0;
return x  y ? 1 : -1;
  }
Below is a variant of the compare code and a comparison with the cost of 
the current compare code:


public static int compare(float x, float y)
{
  int ix = floatAsIntBits(x);
  int iy = floatAsIntBits(y);
  if (ix == iy) return 0;
  if (isNaN(x)) return 1;
  if (isNaN(y)) return -1;
  int ix_sign = ix31;
  int iy_sign = iy31;
  if (ix_sign == iy_sign) {
return x  y ? 1 : -1;
  } else {
return ix_sign - iy_sign;
  }
}

Case: x == y neither are NaN or 0.0
New Cost: 2 float as ints, 1 int compare
Old Cost: 5 float compares

Case: x  y and different sign
New Cost: 2 float as ints, 2 int compares, 2 float compares, 2 shifts, 
one subtract

Old Cost: 6 float compares

Case: x  y and same sign
New Cost: 2 float as ints, 2 int compares, 3 float compares, 2 shifts
Old Cost: 6 float compares

Case: x is NaN
New Cost: 2 float as ints, 1 int compare, 1 float compare
Old Cost: 2 float compares

Case: y is NaN
New Cost: 2 float as ints, 1 int compare, 2 float compares
Old Cost: 2 float compares

Case: x == 0.0 and y == 0.0
New Cost: either 2 float as ints, 1 int compare or 2 float as ints, 2 
int compares, 2 float compares, 2 shifts, one subtract
Old Cost: 4 float compares, 2 float divides, 1 float subtract, 1 float 
to int


The same code but for doubles would be:

public static int compare(double x, double y)
{
  long lx = doubleAsLongBits(x);
  long ly = doubleAsLongBits(y);
  if (lx == ly) return 0;
  if (isNaN(x)) return 1;
  if (isNaN(y)) return -1;
  int lx_sign = (int)(lx63);
  int ly_sign = (int)(ly63);
  if (lx_sign == ly_sign) {
return x  y ? 1 : -1;
  } else {
return lx_sign - ly_sign;
  }
}

So the case when y is a NaN is slower with the new code but I think all 
of the more common cases are similar or faster. Of course it depends on 
the speed of all the operations. If you cared about a CPU with no 
floating point, the new code is a lot faster. If you've got great 
floating point and a lot of cases of y being a NaN the old code will be 
better. My guess is that in the general case the new code wins out. 
There may be a bug I can't see in this code :-)


Regards,
Ian



Re: Float/Double compare

2007-06-30 Thread Ian Rogers
In terms of performance I just tried sorting an array of floats with the 
new code (floatAsIntBits should have been floatToIntBits, sorry). The 
test was to initialize an array of floats backwards and then sort it to 
be ascending. Running a large enough array and enough iterations to get 
a ~4 second run, using the Jikes RVM's optimizing compiler, the speed up 
was around 7.77% on a Pentium 4 Linux box.


Ian



Migration to generics opens up exciting optimization opportunities from annotations

2006-11-30 Thread Ian Rogers

Hi,

I believe there are some interesting optimization opportunities that 
flow from the move to generics that enables the proper use of 
annotations. For example a code sequence such as:


static final int specialValue = 123;
void foo() {
  Integer bar1 = Integer.valueOf(specialValue);
  
  invoke some methods
  ...
  Integer bar2 = Integer.valueOf(specialValue);
  ...
}

could be optimized to:

static final int specialValue = 123;
void foo() {
  Integer bar1 = Integer.valueOf(specialValue);
  
  invoke some methods
  ...
  Integer bar2 = bar1;
  ...
}

if we knew that the intCache were holding an immutable value. Actually 
there are more exciting optimizations discussed in this paper by Igor 
Pechtchanski and Vivek Sarkar, in particular because of the immutability 
of Strings:


http://citeseer.ist.psu.edu/pechtchanski02immutability.html

I'm interested in adding these optimization to the Jikes RVM, but 
clearly the annotations need adding to Classpath. I was wondering what 
kind of response this would get? I can imagine a gnu.pragma or 
gnu.compilerhint package containing such annotations. It could also 
contain similar compiler hints to those found in GCC attributes. The 
Jikes RVM uses a package called org.vmmagic.pragma for some other 
compiler tricks.


Interested in your responses, thanks,

Ian Rogers
--
http://www.cs.man.ac.uk/~irogers



Re: Trouble building x86 32-bit classpath on an x86-64 machine

2006-10-31 Thread Ian Rogers
Hi Adam,

really the only important flag to build Classpath for x86 rather than
x86-64 on an x86-64 system is -m32 as a compiler flag. The default
x86-64 config file for the Jikes RVM does this by defining CC and CPLUS
to have -m32 at the end. Alternatively compiler flags can be specified
with the environment variables CFLAGS and CXXFLAGS.

I have been trying to capture information on building the Jikes RVM in
the wiki:
http://jikesrvm.sourceforge.net/wiki/index.php/Building
I would welcome help and contributions.

Thanks,

Ian Rogers




[cp-patches] Problem in native/jni/classpath/jcl.c

2006-09-27 Thread Ian Rogers
There's a bug in the Classpath CVS head that's crashing the Jikes RVM
(thanks to Mark for helping me to find it). It's in jcl.c where we
delete a global ref which is actually only a local ref. The following
fixes it.

Thanks,

Ian Rogers

Index: native/jni/classpath/jcl.c
===
RCS file: /sources/classpath/classpath/native/jni/classpath/jcl.c,v
retrieving revision 1.25
diff -u -r1.25 jcl.c
--- native/jni/classpath/jcl.c  17 Sep 2006 19:13:01 -  1.25
+++ native/jni/classpath/jcl.c  27 Sep 2006 09:34:32 -
@@ -75,7 +75,6 @@
 {
   jclass tmp = rawDataClass;
   rawDataClass = (*env)-NewGlobalRef (env, rawDataClass);
-  (*env)-DeleteGlobalRef (env, tmp);
 }

   if (rawDataClass != NULL)
@@ -90,7 +89,6 @@
 {
   jclass tmp = rawDataClass;
   rawDataClass = (*env)-NewGlobalRef (env, rawDataClass);
-  (*env)-DeleteGlobalRef (env, tmp);
 }

   if (rawDataClass != NULL)



Re: [cp-patches] Revise threading description in vmintegration.texinfo

2006-08-19 Thread Ian Rogers
Hi,

I'm resending this updated patch with a hope that someone will commit it
now that I've got all the FSF paper work through.

Thanks,

Ian Rogers

Ian Rogers wrote:
 Hi,
 
 this patch revises the discussion of threading in the VM integration
 guide, as well as fixing a link to the Jikes RVM. A discussion was had
 on classpath@gnu.org on the 29/03/06 under the heading Green threads -
 some experience. The VM integration guide should now be up-to-date on
 this subject, although maybe my description of the problems is a little
 verbose.
 
 Regards,
 
 Ian Rogers
 -- http://www.cs.man.ac.uk/~irogers

Index: doc/vmintegration.texinfo
===
RCS file: /sources/classpath/classpath/doc/vmintegration.texinfo,v
retrieving revision 1.40
diff -u -r1.40 vmintegration.texinfo
--- doc/vmintegration.texinfo	22 Jul 2006 19:59:14 -	1.40
+++ doc/vmintegration.texinfo	18 Aug 2006 15:22:43 -
@@ -144,7 +144,7 @@
 pure GNU Classpath; it is emerging as the preferred platform for
 quickly testing a new build of GNU Classpath.  Licensed under the GPL.
 
[EMAIL PROTECTED] @uref{http://oss.software.ibm.com/jikesrvm,Jikes RVM}
[EMAIL PROTECTED] @uref{http://jikesrvm.sourceforge.net/,Jikes RVM}
 A free runtime environment for Java, written in Java.  Works
 out-of-the-box with pure GNU Classpath.  Features an optimizing JIT.
 Runs on the x86 and PowerPC architectures, on the AIX, Linux, and Mac
@@ -1859,8 +1859,7 @@
 
 Classpath currently uses only JNI 1.1, except for one JNI 1.2 function
 in the JNI Invocation API: GetEnv().  And GetEnv() is only used in the
-``portable native sync'' code, so it's only actually used by Jikes RVM
-and Kaffe.  
+now deprecated ``portable native sync'' code.
 
 A future direction will probably be to require that all VMs provide
 JNI 1.2.  If this poses problems, please raise them on the classpath
@@ -1870,42 +1869,95 @@
 @comment  node-name,  next,  previous,  up
 @section VM Threading Model
 
-Classpath's AWT peers use GTK+.  GTK+ uses GLIB.  Normally, Classpath
-will initialize GLIB's @dfn{gthreads} to use
-the platform's native threading [EMAIL PROTECTED] native threading
-model is pthreads on Linux and AIX, the two platforms Classpath
-currently runs on.}
-
-If the Java runtime doesn't use the native threading model, then you
-will want Classpath to tell GLIB to use the Java threading primitives
-instead.  Otherwise, GLIB would use the native threading model to
-perform operations such as creating thread-local data, and that just
-doesn't work on systems (such as Kaffe in some configurations, and
-such as Jikes RVM) that use @i{m}:@i{n} threading.
-
-Historically, enabling the Java threading primitives had been done at
-build time, by configuring classpath with the
[EMAIL PROTECTED] option.  This had bad consequences,
-though -- it meant that the prebuild GNU Classpath package distributed
-with Debian GNU/Linux would not be usable with VMs that could
-otherwise have used it.  Instead, we encourage
-the use of the Java system property
[EMAIL PROTECTED]  A VM that wants
-GLIB to use the Java threading primitives should modify
[EMAIL PROTECTED]()} to include code like the
-following:
-
[EMAIL PROTECTED]
-static void insertSystemProperties(Properties @var{p}) 
[EMAIL PROTECTED] example
-...
[EMAIL PROTECTED]
[EMAIL PROTECTED](gnu.classpath.awt.gtk.portable.native.sync, true);
[EMAIL PROTECTED] example
-
-So, the configure option
[EMAIL PROTECTED] is deprecated, and should go away in a
-subsequent release of GNU Classpath.
+VM authors can implement a number of different threading models. When
+native code is also threaded there is the potential for one threading
+model to deadlock the other. The
[EMAIL PROTECTED]://java.sun.com/docs/books/jni/html/other.html#29406,Java
+Native Interface Programmer's Guide and Specification} suggests
+consulting VM documentation in such situations. Classpath uses
+existing libraries, for example the AWT peers can use the GTK+
+graphics library. As these libraries assume a different threading
+model, there is the potential for the native code to deadlock a VM.
+
+The different threading models available to a VM author are:
[EMAIL PROTECTED]
[EMAIL PROTECTED]
[EMAIL PROTECTED] threads}: Map a Java thread to an underlying operating system
+thread (normally a POSIX compatible pthread). This approach reduces
+the potential for deadlock as there is only one thread scheduling
+mechanism.
[EMAIL PROTECTED]
[EMAIL PROTECTED] threads 1}: Green threads are threads scheduled by the VM,
+typically by switching swapping registers. In early VMs green threads
+were seen as advantageous as they didn't require the operating system
+to resechedule, save and swap all of a threads registers. The green
+thread 1 model switches thread on an externally created event, such as
+a timer interrupt. An example of a VM using this approach is Kaffe
+configured with its jthreads model.
[EMAIL PROTECTED]
[EMAIL PROTECTED] threads 2

Re: Q: userland threads and system calls

2006-08-19 Thread Ian Rogers
Hi Casey,

there were a series of e-mails on green threads a while ago:

http://developer.classpath.org/pipermail/classpath/2006-March/000712.html

For the Jikes RVM we assume that most system and library calls are fine,
but we special case a few in the syswrap.C file:

http://svn.sourceforge.net/viewvc/jikesrvm/rvmroot/trunk/rvm/src/tools/bootImageRunner/syswrap.C?view=markup

We actually special case very few as we replace the standard socket
library with our own non-blocking variant (which is also slightly
problematic).

The special cases we have are:

select and poll, to support IO
pthread_mutex_lock and pthread_cond_wait, to avoid these waiting on a
lock already held by the current pthread (and instead calling a Java
thread yield)

Currently we're thinking of dropping green threads in favor of pthreads
as it would remove our IO problems, but this is a fairly fundamental
change to the runtime. It strikes me that mileages will also vary
whether you have a green threads 1 or 2 model (see my previous post). We
have a green thread 2 model, which can't schedule another Java thread
unless the current Java thread hangs itself up.

I will repost the patch I wrote the VM integration guide describing this
too.

Regards,

Ian Rogers

Casey Marshall wrote:
 This is a general question for those using Classpath with VMs that
 support UNIXy C implementations of native methods, but who use userland
 (green) threads as opposed to native threads.
 
 My understanding is that the core issue is that you can't become blocked
 in a system call, because that will block all threads from running. So
 is this restriction *exclusively* for system calls that might block?
 accept() and read() clearly may block, so we should provide wrappers
 around them that can be replaced with a userland thread-friendly
 version, but bind(), getsockopt(), etc. don't seem like they would (they
 won't, for example, ever return EAGAIN or EINTR, according to the man
 pages). So do fast system calls like this need to be wrapped for user
 threads, or will it suffice to just call them directly?
 
 I also realize that the assumption foo() will not block, because the
 docs say so may not be valid everywhere, since UNIX operating systems
 are a minefield of subtle incompatibilities. Some of these functions
 *should* just be copying kernel structures into the arguments, but do
 any syscalls block, when we should assume that they won't?
 
 Thanks.
 




[cp-patches] Revise threading description in vmintegration.texinfo

2006-04-19 Thread Ian Rogers

Hi,

this patch revises the discussion of threading in the VM integration 
guide, as well as fixing a link to the Jikes RVM. A discussion was had 
on classpath@gnu.org on the 29/03/06 under the heading Green threads - 
some experience. The VM integration guide should now be up-to-date on 
this subject, although maybe my description of the problems is a little 
verbose.


Regards,

Ian Rogers
-- http://www.cs.man.ac.uk/~irogers
Index: vmintegration.texinfo
===
RCS file: /sources/classpath/classpath/doc/vmintegration.texinfo,v
retrieving revision 1.27
diff -u -r1.27 vmintegration.texinfo
--- vmintegration.texinfo	17 Apr 2006 12:22:19 -	1.27
+++ vmintegration.texinfo	19 Apr 2006 10:56:55 -
@@ -143,7 +143,7 @@
 pure GNU Classpath; it is emerging as the preferred platform for
 quickly testing a new build of GNU Classpath.  Licensed under the GPL.
 
[EMAIL PROTECTED] @uref{http://oss.software.ibm.com/jikesrvm,Jikes RVM}
[EMAIL PROTECTED] @uref{http://jikesrvm.sourceforge.net/,Jikes RVM}
 A free runtime environment for Java, written in Java.  Works
 out-of-the-box with pure GNU Classpath.  Features an optimizing JIT.
 Runs on the x86 and PowerPC architectures, on the AIX, Linux, and Mac
@@ -1426,8 +1426,7 @@
 
 Classpath currently uses only JNI 1.1, except for one JNI 1.2 function
 in the JNI Invocation API: GetEnv().  And GetEnv() is only used in the
-``portable native sync'' code, so it's only actually used by Jikes RVM
-and Kaffe.  
+now deprecated ``portable native sync'' code.
 
 A future direction will probably be to require that all VMs provide
 JNI 1.2.  If this poses problems, please raise them on the classpath
@@ -1437,42 +1436,95 @@
 @comment  node-name,  next,  previous,  up
 @section VM Threading Model
 
-Classpath's AWT peers use GTK+.  GTK+ uses GLIB.  Normally, Classpath
-will initialize GLIB's @dfn{gthreads} to use
-the platform's native threading [EMAIL PROTECTED] native threading
-model is pthreads on Linux and AIX, the two platforms Classpath
-currently runs on.}
-
-If the Java runtime doesn't use the native threading model, then you
-will want Classpath to tell GLIB to use the Java threading primitives
-instead.  Otherwise, GLIB would use the native threading model to
-perform operations such as creating thread-local data, and that just
-doesn't work on systems (such as Kaffe in some configurations, and
-such as Jikes RVM) that use @i{m}:@i{n} threading.
-
-Historically, enabling the Java threading primitives had been done at
-build time, by configuring classpath with the
[EMAIL PROTECTED] option.  This had bad consequences,
-though -- it meant that the prebuild GNU Classpath package distributed
-with Debian GNU/Linux would not be usable with VMs that could
-otherwise have used it.  Instead, we encourage
-the use of the Java system property
[EMAIL PROTECTED]  A VM that wants
-GLIB to use the Java threading primitives should modify
[EMAIL PROTECTED]()} to include code like the
-following:
-
[EMAIL PROTECTED]
-static void insertSystemProperties(Properties @var{p}) 
[EMAIL PROTECTED] example
-...
[EMAIL PROTECTED]
[EMAIL PROTECTED](gnu.classpath.awt.gtk.portable.native.sync, true);
[EMAIL PROTECTED] example
-
-So, the configure option
[EMAIL PROTECTED] is deprecated, and should go away in a
-subsequent release of GNU Classpath.
+VM authors can implement a number of different threading models. When
+native code is also threaded there is the potential for one threading
+model to deadlock the other. The
[EMAIL PROTECTED]://java.sun.com/docs/books/jni/html/other.html#29406,Java
+Native Interface Programmer's Guide and Specification} suggests
+consulting VM documentation in such situations. Classpath uses
+existing libraries, for example the AWT peers can use the GTK+
+graphics library. As these libraries assume a different threading
+model, there is the potential for the native code to deadlock a VM.
+
+The different threading models available to a VM author are:
[EMAIL PROTECTED]
[EMAIL PROTECTED]
[EMAIL PROTECTED] threads}: Map a Java thread to an underlying operating system
+thread (normally a POSIX compatible pthread). This approach reduces
+the potential for deadlock as there is only one thread scheduling
+mechanism.
[EMAIL PROTECTED]
[EMAIL PROTECTED] threads 1}: Green threads are threads scheduled by the VM,
+typically by switching swapping registers. In early VMs green threads
+were seen as advantageous as they didn't require the operating system
+to resechedule, save and swap all of a threads registers. The green
+thread 1 model switches thread on an externally created event, such as
+a timer interrupt. An example of a VM using this approach is Kaffe
+configured with its jthreads model.
[EMAIL PROTECTED]
[EMAIL PROTECTED] threads 2}: The essential difference with this model is to
+not switch threads on an event, but at fixed points in the code being
+executed by the VM. Points chosen could be backward branches (loops

[cp-patches] Patch: Reduce number of compilation warnings

2006-04-13 Thread Ian Rogers

Hi,

the attached patch reduces the number of warnings emitted when compiling 
classpath with jikes (in particular as part of the Jikes RVM build 
process). The warnings were:


1)  by a negative amount - this was in the code to achieve a rotate. 
To make the code readable the patch adds a rotate method which is called 
instead. As the rotate method is private it should be an excellent 
candidate for inlining and not impact on performance.
2) final fields that could have been static weren't - so I made them 
static :-)
3) reference of a static field from an instance rather than from the 
class - made to reference the class instead
4) the inner class EditorContainer of DefaultTreeCellEditor had a method 
whose name matched that of being constructor but it wasn't a constructor 
- the comments in the code suggested this method shouldn't be there, so 
I removed it


The only remaining warning was with 
./gnu/java/rmi/registry/RegistryImpl_Stub.java that contains private 
methods whose names begin with $ and that could possibly (but quite 
unlikely) create a naming conflict with an automatically generated 
class/field. This class is automatically generated by rmic, and I 
couldn't see in rmic where the $ signs were creeping in :-(


The patch is just a suggestion, but it cleans up watching a build for 
me, which could potentially help spot new bugs in the future.


Regards,

Ian Rogers
-- http://www.cs.man.ac.uk/~irogers
Index: external/sax/org/xml/sax/helpers/ParserAdapter.java
===
RCS file: /sources/classpath/classpath/external/sax/org/xml/sax/helpers/ParserAdapter.java,v
retrieving revision 1.1
diff -u -r1.1 ParserAdapter.java
--- external/sax/org/xml/sax/helpers/ParserAdapter.java	23 Dec 2004 22:38:42 -	1.1
+++ external/sax/org/xml/sax/helpers/ParserAdapter.java	13 Apr 2006 15:23:57 -
@@ -561,7 +561,7 @@
 			// note funky case:  localname can be null
 			// when declaring the default prefix, and
 			// yet the uri isn't null.
-			atts.addAttribute (nsSupport.XMLNS, prefix,
+			atts.addAttribute (NamespaceSupport.XMLNS, prefix,
 attQName.intern(), type, value);
 			else
 			atts.addAttribute (, ,
Index: gnu/java/security/hash/MD4.java
===
RCS file: /sources/classpath/classpath/gnu/java/security/hash/MD4.java,v
retrieving revision 1.1
diff -u -r1.1 MD4.java
--- gnu/java/security/hash/MD4.java	26 Jan 2006 02:25:10 -	1.1
+++ gnu/java/security/hash/MD4.java	13 Apr 2006 15:23:58 -
@@ -222,107 +222,115 @@
 dd = d;
 
 aa += ((bb  cc) | ((~bb)  dd)) + X0;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  bb) | ((~aa)  cc)) + X1;
-dd = dd  7 | dd  -7;
+dd = rotate(dd, 7);
 cc += ((dd  aa) | ((~dd)  bb)) + X2;
-cc = cc  11 | cc  -11;
+cc = rotate(cc, 11);
 bb += ((cc  dd) | ((~cc)  aa)) + X3;
-bb = bb  19 | bb  -19;
+bb = rotate(bb, 19);
 aa += ((bb  cc) | ((~bb)  dd)) + X4;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  bb) | ((~aa)  cc)) + X5;
-dd = dd  7 | dd  -7;
+dd = rotate(dd, 7);
 cc += ((dd  aa) | ((~dd)  bb)) + X6;
-cc = cc  11 | cc  -11;
+cc = rotate(cc, 11);
 bb += ((cc  dd) | ((~cc)  aa)) + X7;
-bb = bb  19 | bb  -19;
+bb = rotate(bb, 19);
 aa += ((bb  cc) | ((~bb)  dd)) + X8;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  bb) | ((~aa)  cc)) + X9;
-dd = dd  7 | dd  -7;
+dd = rotate(dd, 7);
 cc += ((dd  aa) | ((~dd)  bb)) + X10;
-cc = cc  11 | cc  -11;
+cc = rotate(cc, 11);
 bb += ((cc  dd) | ((~cc)  aa)) + X11;
-bb = bb  19 | bb  -19;
+bb = rotate(bb, 19);
 aa += ((bb  cc) | ((~bb)  dd)) + X12;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  bb) | ((~aa)  cc)) + X13;
-dd = dd  7 | dd  -7;
+dd = rotate(dd, 7);
 cc += ((dd  aa) | ((~dd)  bb)) + X14;
-cc = cc  11 | cc  -11;
+cc = rotate(cc, 11);
 bb += ((cc  dd) | ((~cc)  aa)) + X15;
-bb = bb  19 | bb  -19;
+bb = rotate(bb, 19);
 
 aa += ((bb  (cc | dd)) | (cc  dd)) + X0 + 0x5a827999;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  (bb | cc)) | (bb  cc)) + X4 + 0x5a827999;
-dd = dd  5 | dd  -5;
+dd = rotate(dd, 5);
 cc += ((dd  (aa | bb)) | (aa  bb)) + X8 + 0x5a827999;
-cc = cc  9 | cc  -9;
+cc = rotate(cc, 9);
 bb += ((cc  (dd | aa)) | (dd  aa)) + X12 + 0x5a827999;
-bb = bb  13 | bb  -13;
+bb = rotate(bb, 13);
 aa += ((bb  (cc | dd)) | (cc  dd)) + X1 + 0x5a827999;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  (bb | cc)) | (bb  cc)) + X5 + 0x5a827999;
-dd = dd  5 | dd  -5;
+dd = rotate(dd, 5);
 cc += ((dd  (aa | bb)) | (aa  bb)) + X9 + 0x5a827999;
-cc = cc  9 | cc  -9;
+cc = rotate(cc, 9);
 bb += ((cc  (dd | aa)) | (dd  aa)) + X13 + 0x5a827999;
-bb

Re: [cp-patches] Patch: Reduce number of compilation warnings

2006-04-13 Thread Ian Rogers

Thanks Tom,

I thought I'd fix all the warnings and wait for people to complain. I 
agree with what you say and I've attached a fixed patch for just MD4 and 
MD5, any idea on how to stop the $ symbols being generated by rmic? They 
are on private fields so altering the names shouldn't matter.


Ian

Tom Tromey wrote:

Ian +  private static int rotate(int x, int y) {
Ian +return (x  y) | (x  -y);
Ian +  }

Coding style... open brace goes on its own line.

Tom
  


Index: gnu/java/security/hash/MD4.java
===
RCS file: /sources/classpath/classpath/gnu/java/security/hash/MD4.java,v
retrieving revision 1.1
diff -u -r1.1 MD4.java
--- gnu/java/security/hash/MD4.java	26 Jan 2006 02:25:10 -	1.1
+++ gnu/java/security/hash/MD4.java	13 Apr 2006 18:59:37 -
@@ -222,107 +222,116 @@
 dd = d;
 
 aa += ((bb  cc) | ((~bb)  dd)) + X0;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  bb) | ((~aa)  cc)) + X1;
-dd = dd  7 | dd  -7;
+dd = rotate(dd, 7);
 cc += ((dd  aa) | ((~dd)  bb)) + X2;
-cc = cc  11 | cc  -11;
+cc = rotate(cc, 11);
 bb += ((cc  dd) | ((~cc)  aa)) + X3;
-bb = bb  19 | bb  -19;
+bb = rotate(bb, 19);
 aa += ((bb  cc) | ((~bb)  dd)) + X4;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  bb) | ((~aa)  cc)) + X5;
-dd = dd  7 | dd  -7;
+dd = rotate(dd, 7);
 cc += ((dd  aa) | ((~dd)  bb)) + X6;
-cc = cc  11 | cc  -11;
+cc = rotate(cc, 11);
 bb += ((cc  dd) | ((~cc)  aa)) + X7;
-bb = bb  19 | bb  -19;
+bb = rotate(bb, 19);
 aa += ((bb  cc) | ((~bb)  dd)) + X8;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  bb) | ((~aa)  cc)) + X9;
-dd = dd  7 | dd  -7;
+dd = rotate(dd, 7);
 cc += ((dd  aa) | ((~dd)  bb)) + X10;
-cc = cc  11 | cc  -11;
+cc = rotate(cc, 11);
 bb += ((cc  dd) | ((~cc)  aa)) + X11;
-bb = bb  19 | bb  -19;
+bb = rotate(bb, 19);
 aa += ((bb  cc) | ((~bb)  dd)) + X12;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  bb) | ((~aa)  cc)) + X13;
-dd = dd  7 | dd  -7;
+dd = rotate(dd, 7);
 cc += ((dd  aa) | ((~dd)  bb)) + X14;
-cc = cc  11 | cc  -11;
+cc = rotate(cc, 11);
 bb += ((cc  dd) | ((~cc)  aa)) + X15;
-bb = bb  19 | bb  -19;
+bb = rotate(bb, 19);
 
 aa += ((bb  (cc | dd)) | (cc  dd)) + X0 + 0x5a827999;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  (bb | cc)) | (bb  cc)) + X4 + 0x5a827999;
-dd = dd  5 | dd  -5;
+dd = rotate(dd, 5);
 cc += ((dd  (aa | bb)) | (aa  bb)) + X8 + 0x5a827999;
-cc = cc  9 | cc  -9;
+cc = rotate(cc, 9);
 bb += ((cc  (dd | aa)) | (dd  aa)) + X12 + 0x5a827999;
-bb = bb  13 | bb  -13;
+bb = rotate(bb, 13);
 aa += ((bb  (cc | dd)) | (cc  dd)) + X1 + 0x5a827999;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  (bb | cc)) | (bb  cc)) + X5 + 0x5a827999;
-dd = dd  5 | dd  -5;
+dd = rotate(dd, 5);
 cc += ((dd  (aa | bb)) | (aa  bb)) + X9 + 0x5a827999;
-cc = cc  9 | cc  -9;
+cc = rotate(cc, 9);
 bb += ((cc  (dd | aa)) | (dd  aa)) + X13 + 0x5a827999;
-bb = bb  13 | bb  -13;
+bb = rotate(bb, 13);
 aa += ((bb  (cc | dd)) | (cc  dd)) + X2 + 0x5a827999;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  (bb | cc)) | (bb  cc)) + X6 + 0x5a827999;
-dd = dd  5 | dd  -5;
+dd = rotate(dd, 5);
 cc += ((dd  (aa | bb)) | (aa  bb)) + X10 + 0x5a827999;
-cc = cc  9 | cc  -9;
+cc = rotate(cc, 9);
 bb += ((cc  (dd | aa)) | (dd  aa)) + X14 + 0x5a827999;
-bb = bb  13 | bb  -13;
+bb = rotate(bb, 13);
 aa += ((bb  (cc | dd)) | (cc  dd)) + X3 + 0x5a827999;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += ((aa  (bb | cc)) | (bb  cc)) + X7 + 0x5a827999;
-dd = dd  5 | dd  -5;
+dd = rotate(dd, 5);
 cc += ((dd  (aa | bb)) | (aa  bb)) + X11 + 0x5a827999;
-cc = cc  9 | cc  -9;
+cc = rotate(cc, 9);
 bb += ((cc  (dd | aa)) | (dd  aa)) + X15 + 0x5a827999;
-bb = bb  13 | bb  -13;
+bb = rotate(bb, 13);
 
 aa += (bb ^ cc ^ dd) + X0 + 0x6ed9eba1;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += (aa ^ bb ^ cc) + X8 + 0x6ed9eba1;
-dd = dd  9 | dd  -9;
+dd = rotate(dd, 9);
 cc += (dd ^ aa ^ bb) + X4 + 0x6ed9eba1;
-cc = cc  11 | cc  -11;
+cc = rotate(cc, 11);
 bb += (cc ^ dd ^ aa) + X12 + 0x6ed9eba1;
-bb = bb  15 | bb  -15;
+bb = rotate(bb, 15);
 aa += (bb ^ cc ^ dd) + X2 + 0x6ed9eba1;
-aa = aa  3 | aa  -3;
+aa = rotate(aa, 3);
 dd += (aa ^ bb ^ cc) + X10 + 0x6ed9eba1;
-dd = dd  9 | dd  -9;
+dd = rotate(dd, 9);
 cc += (dd ^ aa ^ bb) + X6 + 0x6ed9eba1;
-cc = cc  11 | cc  -11;
+cc = rotate(cc, 11);
 bb += (cc ^ dd ^ aa) + X14 + 0x6ed9eba1;
-bb = bb  15 | bb  -15;
+bb = rotate(bb, 15);
 aa += (bb ^ cc ^ dd) + X1 + 

Re: [cp-patches] Patch: Reduce number of compilation warnings

2006-04-13 Thread Ian Rogers

Hi Audrius,

Wouldn't it be better to regenerate the sources rather than manually 
remove the $ signs? I don't know how the RMI compiler generated the 
sources. I'm happy to modify the files by hand otherwise.


Thanks!

Ian

Audrius Meskauskas wrote:
any idea on how to stop the $ symbols being generated by rmic? They 
are on private fields so altering the names shouldn't matter.
I would say, just rename these private fields to match our coding 
standard. I see no reason to use the reserved characters there. This 
class is not generated during the each build and can be edited like 
any other.


Our RMI source code generator in RMIC package is currently configured 
to follow the standard Classpath naming rules and would not use the 
dollar sign for the names of the private fields.

Regards
Audrius.







Re: Green threads - some experience

2006-03-31 Thread Ian Rogers

Archie Cobbs wrote:

IMHO using POSIX threads is the only right answer for a multi-platform
JVM. You have no other choice except to leave it up to the specific
platform to then implement POSIX threads efficiently.

For example, on Linux where each POSIX thread is a cloned process, it's
Linux's fault (not the JVM's fault) if that doesn't scale well. For 
example,

other OS's don't have such heavyweight threads. FreeBSD's KSE's are an
example of a better tradeoff using M:N user:kernel threading.
I agree with you. I think it's always the case that Java threads are 
going to be better than POSIX threads though, as with some commodity 
processors, in particular I'm thinking of Cell, you no longer have a 
shared memory model. In such a situation you could use a distributed 
JVM, such as JESSICA2 - that's built on top of Kaffe :-). So whilst 
implementing a JVM assuming POSIX threads is a good idea to run on many 
platforms, there are legitimate reasons why you may want to be flexible 
and not assume a 1-to-1 mapping of Java threads to POSIX threads, and of 
course avoid native code.


Regards,

Ian



Green threads - some experience

2006-03-29 Thread Ian Rogers

Hi,

I'd just like to describe my experiences of getting m-to-n threading 
going with classpath gtk peers and the Jikes RVM. It could possibly be 
instructive for developers and/or other JVMs.


There are different models of threading:

1) native threads: map Java threads to native pthreads - talking to 
people suggests this is the preferred method by classpath developers and 
is in the widest use
2) green threads 1: run Java threads as a single thread then on timer 
switch the running thread. This method is used by Kaffe's jthreads.
3) green threads 2: run Java threads as a single thread, on a timer 
interrupt set a flag indicating a yield is desired. At points in the 
code test this flag and yield if necessary.
4) m-to-n: run m green Java threads on n native threads. This approach 
is adopted in the Jikes RVM with green threads 2.


The biggest problem is:

Java threads can call into native code. This native code can call out to 
Java code. Not all native code will return to Java code or call out to 
Java code (e.g. gtk_main). If your JVM uses the green threads 2 model 
this presents a problem scheduling other threads.


The Jikes RVM solves this problem by having a back up thread that 
non-blocked Java threads can be switched onto. The original Java thread 
continues to be blocked on the native thread. However, if the back up 
thread becomes blocked there's a problem. To reduce and optimise this 
problem the Jikes RVM replaces some system calls with non-blocking 
alternatives.


The AWT peer problems were caused primarily by pthread mechanisms being 
used by GTK. These are wrapped in a library called gthreads. A Java 
thread would:

1) enter some native code that acquired a pthread mutex
2) call back into the JVM
3) the JVM would switch Java thread
4) the Java thread would call code that required the original mutex and 
block in native code not allowing other threads to get scheduled


To solve this there is the portable native sync option with classpath. 
This option swaps the gthread mechanisms with ones that call back into 
the JVM. Unfortunately it is broken, will only work for GTK code and 
won't work if there is already GTK code using the gthread library (for 
example, if the JVM is a plugin).


Another option is to modify classpath so that at the points where mutexs 
are acquired, if a mutex is busy then call back into the JVM. However, 
this option isn't desirable as its not required for a lot of JVMs.


Another option is to try to stop the Java threads entering native code 
if on that native thread a Java thread is already in native code. This 
proved to be buggy and slow, it is likely the scheduler needs work with 
this option.


So the simplest solution[1] was to hijack the pthread mutex locking and 
waiting calls and replace them with versions that call back into the 
JVM. This works well but the final implementation isn't quite bug free.


[1] changing the threading model to using native threads wasn't 
considered simple.


The current Jikes RVM CVS head is using this mechanism and is no longer 
using portable native sync. It is very likely that this code is now 
redundant.


The JNI spec. and programmers guide section 8.1.5:
http://java.sun.com/docs/books/jni/html/other.html#29406
describes consulting JVM documentation before embarking on threaded 
native code.


Regards,

Ian Rogers
---
http://www.cs.man.ac.uk/~irogers/



Re: Green threads - some experience

2006-03-29 Thread Ian Rogers

Hi Nic,

I think the long term view is to switch to POSIX threads. Having used 
the Jikes RVM for an OS like project, relying on native threads wouldn't 
have been desirable. In theory green thread context switches should be 
possible in a few instructions whereas a full context switch takes a few 
hundred. I guess its all down to the situation the JVM is trying to 
optimise for. Microsoft's Singularity OS makes an advantage out of not 
requiring full context switches. If you have as many hardware contexts 
as threads, then green threads would be an unnecessary overhead.


Ian

Nic wrote:

Intersting post Ian.

Maybe I'm linux 2.6 biased... but wouldn't simply using POSIX threads
be so much better? NPTL is so nice.


Nic

  





Re: [cp-patches] RFC: gnu.java.math.MPN optimizations

2006-03-23 Thread Ian Rogers
I have created a project to benchmark the java.math library (and these 
proposed changes). From looking at GMP it is amazing how complex these 
libraries can be made. The benchmark project is at 
http://bigintbench.sourceforge.net/. My first goal is to port some of 
the gmp benchmark programs. Interest welcomed.


Many thanks,

Ian Rogers
-- http://www.cs.man.ac.uk/~irogers/



[cp-patches] RFC: gnu.java.math.MPN optimizations

2006-03-22 Thread Ian Rogers

Hi,

sorry for not really knowing what the etiquette should be here. This 
patch alters the MPN class so that when performing adds and subtracts it 
avoids the use of longs. This is possible by an unsigned_less_than 
operation that itself uses longs, but any tree pattern matcher (such as 
those produced by iburg) should be able to convert into an unsigned 
integer comparison. ie match:
boolcmp: BOOLEAN_CMP_INT(LONG_AND(register, INT_CONSTANT), 
LONG_AND(register, INT_CONSTANT))
where the INT_CONSTANTs are both 0xL the boolean operation is 
less than and the emitted code just does an unsigned integer compare on 
the two registers.
In any case the revised code has fewer long/int operations, I believe. 
I've also not tested the code, so I'm really just putting it here to 
generate discussion.


Thanks,

Ian Rogers
-- http://www.cs.man.ac.uk/~irogers

--- MPN.java	2005-07-02 21:32:13.0 +0100
+++ MPN.hack	2006-03-22 10:55:05.0 +
@@ -47,68 +47,66 @@
  * (at least on platforms that use 32-bit limbs).
  */
 
 public class MPN
 {
+  /**
+	* Perform an unsigned less than comparison on two signed integers
+	*/
+  private static boolean unsigned_less_than(int x, int y)
+  {
+	 return ((long)x  0xL)  ((long)y  0xL);
+  }
   /** Add x[0:size-1] and y, and write the size least
* significant words of the result to dest.
* Return carry, either 0 or 1.
* All values are unsigned.
* This is basically the same as gmp's mpn_add_1. */
   public static int add_1 (int[] dest, int[] x, int size, int y)
   {
-long carry = (long) y  0xL;
-for (int i = 0;  i  size;  i++)
-  {
-	carry += ((long) x[i]  0xL);
-	dest[i] = (int) carry;
-	carry = 32;
-  }
-return (int) carry;
+	 boolean carry = false;
+	 for (int i = 0; i  size; i++) {
+		int result = x[i] + y + (carry ? 1 : 0);
+		carry = unsigned_less_than(result, x[i]);
+		dest[i] = result;
+	 }
+	 return carry ? 1 : 0;
   }
 
   /** Add x[0:len-1] and y[0:len-1] and write the len least
* significant words of the result to dest[0:len-1].
* All words are treated as unsigned.
* @return the carry, either 0 or 1
* This function is basically the same as gmp's mpn_add_n.
*/
   public static int add_n (int dest[], int[] x, int[] y, int len)
   {
-long carry = 0;
-for (int i = 0; i  len;  i++)
-  {
-	carry += ((long) x[i]  0xL)
-	  + ((long) y[i]  0xL);
-	dest[i] = (int) carry;
-	carry = 32;
-  }
-return (int) carry;
+	 boolean carry = false;
+	 for (int i = 0; i  size; i++) {
+		int result = x[i] + y[i] + (carry ? 1 : 0);
+		carry = unsigned_less_than(result, x[i]);
+		dest[i] = result;
+	 }
+	 return carry ? 1 : 0;
   }
 
   /** Subtract Y[0:size-1] from X[0:size-1], and write
* the size least significant words of the result to dest[0:size-1].
* Return borrow, either 0 or 1.
* This is basically the same as gmp's mpn_sub_n function.
*/
 
-  public static int sub_n (int[] dest, int[] X, int[] Y, int size)
+  public static int sub_n (int[] dest, int[] x, int[] y, int size)
   {
-int cy = 0;
-for (int i = 0;  i  size;  i++)
-  {
-	int y = Y[i];
-	int x = X[i];
-	y += cy;	/* add previous carry to subtrahend */
-	// Invert the high-order bit, because: (unsigned) X  (unsigned) Y
-	// iff: (int) (X^0x8000)  (int) (Y^0x8000).
-	cy = (y^0x8000)  (cy^0x8000) ? 1 : 0;
-	y = x - y;
-	cy += (y^0x8000)  (x ^ 0x8000) ? 1 : 0;
-	dest[i] = y;
-  }
-return cy;
+	 boolean borrow = false;
+	 for (int i = 0; i  size; i++) {
+		int subtrahend = y[i] + (borrow ? 1 : 0);
+		int result = x[i] - subtrahend;
+		borrow = unsigned_less_than(x[i], subtrahend);
+		dest[i] = result;
+	 }
+	 return borrow ? 1 : 0;
   }
 
   /** Multiply x[0:len-1] by y, and write the len least
* significant words of the product to dest[0:len-1].
* Return the most significant word of the product.


Re: JNI calls that don't return

2006-03-08 Thread Ian Rogers

Hi David,

I agree the quote is from a book and that book isn't a specification. As 
core library writers people can do what they want with the JNI 
specification and just claim the JVM is broken if it has green threads. 
The book which is targetting application writers who must writer code to 
tackle green or native threaded JVMs doesn't have this luxury, and as 
such is advising using a single thread as a caution in this situation. I 
don't think this distracts from my points. Classpath can either:


1) only work with native threaded JVMs
2) rely upon the portable native sync code to allow gtk peers to work 
(albeit this system needs fixing) in situations where the JVM isn't a plugin
3) be written to the same JNI standard as would be required for an 
application targetting both green and native threaded code


I think a --enable-green-thread-support configure option and following 
choice 3 would be more appropriate than choices 1 or 2, I am however not 
keen to develop my own branch of classpath :-). I think you back option 
1, so is it inappropriate for classpath to currently have the portable 
native sync code in it?


The other issue of java threads that have called into non-returning JNI 
code tying up native threads in green threaded JVMs is a separate 
related issue and possibly one that can be handled by a system property. 
For example, a property could be called 
gnu.classpath.jni.prefer.java.thread.yield which is a hint that 
non-returning JNI code either calls into java.lang.Thread.yield 
intermittently or avoids using purely native functions (as shown in the 
changes of my first e-mail on this thread).


Thanks,

Ian Rogers

David Daney wrote:

Ian Rogers wrote:
The JNI provides mappings to monitor entry and exit. From google I 
found this document:


http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniref.html#thrd 



That is some tutorial.  Not a specification on how JNI, JVMs or 
threading systems work.





I quote:

You may find that in cases where you want access to a local system 
resource like a MFC window handle or message queue, it is better to 
use one Java |Thread| and access the local threaded native event 
queue or messaging system from within the native code.


So, it would seem to me that this is recommending using a single Java 
thread to access a local system resource which would avoid M-to-N 
threading issues as M would be 1. In classpath we are currently using 
multiple Java threads to access gtk. Whilst the quote is short of 
saying what to do with threading and JNI, I think it is a strong hint 
to programmers that this is a fairly murky area, probably because of 
the mixing of threading models.




It is only a recommendation from a tutorial writer.  The JVM and 
runtime libraries can do whatever they want within the constraints of 
the specifications.

.
.
.


I hope this clears up my point-of-view. Thanks,






Re: JNI calls that don't return

2006-03-08 Thread Ian Rogers

Andrew Haley wrote:
  Currently, to the best of my knowledge, classpath's gtk peer code isn't 
  working with any JVM with M-to-N threading.


No, that's not true, is it?  Surely it works correctly if blocking
system calls are correctly hooked by the thread library.

Andrew.
  

According to:

http://sourceforge.net/tracker/index.php?func=detailaid=1147592group_id=128805atid=712768
(Jikes RVM bug #1147592)

for the only JVM that I know that has M-to-N threading and uses 
classpath, this has been broken since 2004-12-20. I was surprised to 
find this to be the case but if anyone can correct me then I'm happy to 
be wrong. In any case there are problems to hooking the thread library 
which prevent it being used as an approach for JVM plugins.


Thanks,

Ian



Re: JNI calls that don't return

2006-03-08 Thread Ian Rogers

Andrew Haley wrote:

Maybe you know something I don't.  Is there any wordage in the JNI
spec that forbids blocking calls, or suggests that this might be
problematic?  Is there any wordage in the JNI spec that allows the
Jikes RVM to behave in the way that it does with repect to blocking
calls?
  

Andrew,

I am concerned about green threads and problems caused on JVMs using 
them by classpath - the issues with blocking threads and synchronization 
have been highlighted. As I understand the JNI spec. it is designed to 
explain how to access Java objects, invoke Java methods from native 
code. It is a specification of an API and doesn't state what is valid 
native code - it would have to address a large number of APIs to do 
that. The book Advanced Programming for the Java 2 Platform that I 
quoted from does shed some light on what programmers using the JNI API 
can do, and they recommend that JNI programmers accessing MFC in their 
example but GTK for us, should use a single Java thread. I would argue 
their reasoning for this is that it avoids green threading problems. I 
don't believe we should use a single thread to handle GTK peer code, but 
we need to address the problems the current GTK peer code has with green 
threaded JVMs. This leads to 3 solutions:


1) declare green threaded JVMs unsuitable for use with parts of classpath
2) try to fix the portable native sync code - which has issues that I 
keep repeating
3) have conditionally compiled/run code that makes the code behave 
better in the situation of a green threaded JVM


My reasons for posting was to see what people believe is the correct 
route from these 3 alternatives.


Thanks,

Ian



Re: JNI calls that don't return

2006-03-07 Thread Ian Rogers
Thanks for the replies. I have worked further on this and the particular 
issue isn't with GC barriers but with M-to-N threading. In theory if 1 
of the M threads becomes blocked in a JNI call then the other threads 
should be moved onto another of the N underlying native threads. 
Unfortunately, as it's possible to call back into the JVM, the JVM's 
yield code can schedule another thread on the same native thread before 
realising the 1st thread is blocked and now its possibly handling a 
second blocked thread but now on the same native thread. Scheduling 
blocked 2 native threads running on the same native thread requires a 
rewrite to the underlying native thread library. For the gtk peers this 
is done by enabling the portable native sync code, but my experience is 
that this is currently broken (and using it is not advised as it would 
inhibit the using JVM from being used as a plugin in a gthreaded 
application). In any case having a fixed number of N underlying threads 
will probably also become a problem. Anyway, I have a small proposed 
change to gdk_threads_enter for JVMs with M-to-N threading (in gtkpeer.h):


#define M_TO_N_JAVA_THREADING 1

#if M_TO_N_JAVA_THREADING
#define gdk_threads_enter()  \
{\
 JNIEnv *env = cp_gtk_gdk_env();\
 while(g_mutex_trylock(gdk_threads_mutex) == FALSE){ \
jclass thread_class = (*env)-FindClass (env, 
java/lang/Thread); \
jmethodID thread_yield_mth = (*env)-GetStaticMethodID (env, 
thread_class, yield, ()V); \
(*env)-CallStaticVoidMethod (env, thread_class, 
thread_yield_mth); \

 } \
 g_mutex_unlock(gdk_threads_mutex); \
 gdk_threads_enter();   \
}
#endif

it prevents 2 java threads on the same native thread becoming deadlocked 
on the gdk_threads_mutex. Unfortunately the gdk_threads_mutex is 
supposed to be private, but I think accessing it here is suitable.


I think removing the portable native sync code and having specific fixes 
for M-to-N threading is an appropriate change. What are others opinions?


As part of this would it be possible to have versions of JNI routines 
that don't return that at least call Java yield in the case of being on 
a M-to-N threaded JVM?


Thanks,

Ian Rogers



Re: JNI calls that don't return

2006-03-07 Thread Ian Rogers
Currently, to the best of my knowledge, classpath's gtk peer code isn't 
working with any JVM with M-to-N threading. The problem with 
gdk_threads_enter is that it will block if it can't enter the threaded 
code. If, for example, you are mapping the gtk threads to 1 native 
thread then all the threads will quickly block waiting to enter 
gdk_threads_enter. The solution to this is for the gtk peer code not to 
block or to fix the portable native sync code - both require changes to 
classpath and there are reasons not to use portable native syncing. 
Whilst switching to the classpath 1-to-1 thread mapping is a desirable 
change to the JVM it requires a substantial amout of work with no 
developer currently working on it. A compromise could be to supply/apply 
a patch when building classpath with this JVM, but I thought the issues 
raised were of a more generic nature - they'd effect other JVMs that 
implemented M-to-N threading.


Thanks,

Ian Rogers

Andrew Haley wrote:

Ian Rogers writes:
  Thanks for the replies. I have worked further on this and the particular 
  issue isn't with GC barriers but with M-to-N threading.


It's possible that I'm completely missing the point here, but cannot
we simply conclude from this that M-to-N threading in this JVM is
broken?

Andrew.
  





Re: JNI calls that don't return

2006-03-07 Thread Ian Rogers
The JNI provides mappings to monitor entry and exit. From google I found 
this document:


http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniref.html#thrd

I quote:

You may find that in cases where you want access to a local system 
resource like a MFC window handle or message queue, it is better to use 
one Java |Thread| and access the local threaded native event queue or 
messaging system from within the native code.


So, it would seem to me that this is recommending using a single Java 
thread to access a local system resource which would avoid M-to-N 
threading issues as M would be 1. In classpath we are currently using 
multiple Java threads to access gtk. Whilst the quote is short of saying 
what to do with threading and JNI, I think it is a strong hint to 
programmers that this is a fairly murky area, probably because of the 
mixing of threading models.


The code doesn't necessarily have to be blocked in a system call. It 
could be spinning on a mutex and then calling pthread yield. A system 
call is a valid GC point in the JVM, and I'm less worried about them 
than I was previously. Unfortunately blocked system calls do cause some 
pressure within the system and aren't desirable. Each blocked thread 
consumes a thread and there's a fixed number (possibly 1) to be consumed 
- which needs to be addressed :-)


So the situation is that I have 2 threads on 1 pthread. The first thread 
has the gdk threads mutex. The 2nd thread wants the mutex but can't get 
it so calls pthread (not j.l.Thread) yield which yields back to this 
thread and we make no progress. Hijacking the yield and pointing it at 
j.l.Thread.yield is possible (this is done by the portable native sync 
code) but in the case the JVM has been created inside another 
application, for example as a plugin, hijacking the thread yield isn't 
possible. From my investigations, the portable native sync code is 
broken and it doesn't seem clear to me that fixing it will produce the 
best outcome - due to the plugin problem and that this approach will 
never work for anything but code that uses gthreads. I think having a 
modified version of the gtk peer code that addresses M-to-N threading 
issue could be desirable but I wouldn't say it has to be the compile 
time default. It's also possible to say that parts of classpath only 
work for 1-to-1 threaded JVMs.


I hope this clears up my point-of-view. Thanks,

Ian Rogers



JNI calls that don't return

2006-03-03 Thread Ian Rogers

Hi,

There is at least one JNI call that is designed not to return. This is 
that gtkMain native method in gnu.java.awt.peer.gtk.GtkToolkit. Some VMs 
require all Java threads to run upto a garbage collection barrier before 
garbage collection can be performed. If a Java thread never leaves JNI 
code then this will never happen and the VM deadlocks. A solution to 
this is to rewrite the gtkMain loop to something like what follows:


in GtkTookit.java:

 public static void gtkMain() {
try {
   while(true) {
 while(gtkEventsPending()) {
gtkMainIteration();
 }
 Thread.sleep(10);
   }
}
catch(InterruptedException e){}
 }
 public static native void gtkMainIteration();
 private static native boolean gtkEventsPending();

in gnu_java_awt_peer_gtk_GtkToolkit.c (NB regenerate the JNI header files):

JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkMainIteration
(JNIEnv *env __attribute__((unused)), jclass obj __attribute__((unused)))
{
 gdk_threads_enter ();

 gtk_main_iteration ();

 gdk_threads_leave ();
}

JNIEXPORT jboolean JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkEventsPending
(JNIEnv *env __attribute__((unused)), jclass obj __attribute__((unused)))
{
 gboolean pending;

 gdk_threads_enter ();

 pending = gtk_events_pending ();

 gdk_threads_leave ();

 return pending == TRUE ? JNI_TRUE : JNI_FALSE;
}

For performance the nested while loop could be moved into the JNI code.

Is having all JNI code return an option for classpath?

Thanks,

Ian Rogers



java.util.zip

2001-09-03 Thread Ian Rogers

Hi,

I'm trying to build the current cvs tree and can't due to dependencies
between java.util.jar and java.util.zip. It seems there are some source
files still to be checked in for java.util.zip. I can't e-mail the
maintainer directly so I thought I'd ask here if anyone knows when the
missing files will be added to java.util.zip? The web site says things
are nearly complete.

TIA,

Ian Rogers

___
Classpath mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/classpath



Re: Why catch (NullPointerException e)?

2000-08-19 Thread Ian Rogers

Hi,

I think this is a very interesting subject. So far two solutions have
been proposed:

(a) if (sm != null) { sm.XXX(); }
(b) try { sm.XXX(); } catch (NullPointerException e){}

I'd like to propose a third solution. It requires more programming and
results in a larger binary, but on a JIT compiler (such as the one I'm
working on) it may yield the fastest translated code with the lowest
translation/optimisation overhead.

Instead of initialising sm to null I'd like to propose that sm is
initialised to a default object that is a sub class of
SecurityManager. This object doesn't do anything it's merely there to
clear up the confusion caused by having a null object.

The reason this may yield better results is from inlining within the
JIT. If we assume inlining of virtual methods produces code that looks
like a switch statement:

  switch (sm){
  case null: throw new NullPointerException();
  case sm1:  { /* body of method XXX for SecurityManager of type
  sm1 */
   ... break;
 }
  case sm2:  { /* body of method XXX for SecurityManager of type
  sm2 */
   ... break;
 }
  ...
  }

then for (a) we get:

  if (sm != null) { switch (sm){ case null: ... } }

further analysis could remove the double comparison.

for (b) we get:

  try { switch (sm){ case null:... } }
  catch (NullPointerException e) {}

further analysis could place the body of the exception handler in the
null case.

for the third solution we get:

  switch (sm){
  case null: throw new NullPointerException();
  case sm1: ...
  case sm2: ...
  case default_sm: { /* The empty body of the new default method */ }
  ...
  }

This immediately gives the default case an empty body, unlike (b)
which requires an optimisation to do this. It also doesn't require
analysis looking for double comparisons.

I know this makes a lot of assumptions on the workings of a JIT and on
the target JVM for Classpath. I wanted offer this solution to see what
others opinions are.

Cheers,

-- Ian Rogers
-- Dept. Of Computer Science
-- The University of Manchester




  1   2   >