NanoGoat
authoradam <adam@megacz.com>
Fri, 5 Mar 2004 13:10:34 +0000 (13:10 +0000)
committeradam <adam@megacz.com>
Fri, 5 Mar 2004 13:10:34 +0000 (13:10 +0000)
darcs-hash:20040305131034-5007d-98afdb32651d86a47abf169ea64c82ca3d095f7e.gz

13 files changed:
Makefile
Makefile.upstream
jode.conf [deleted file]
lib/libgcj-minimal.jar [deleted file]
src/org/ibex/HTTP.java
src/org/ibex/Platform.java
src/org/ibex/js/Interpreter.java
src/org/ibex/js/Parser.java
src/org/ibex/plat/Linux.cc
src/org/ibex/plat/X11.cc
src/org/ibex/util/NanoGoat.java [moved from src/org/ibex/util/BytecodePruner.java with 64% similarity]
upstream/gcc-3.3/patches/zzz-disable-reflection.patch [deleted file]
upstream/gcc-3.3/patches/zzz-inhibit.reflection.patch [new file with mode: 0644]

index fc64298..91d179a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -19,9 +19,9 @@ dist-clean:
        find upstream -name config.cache -exec rm {} \;
        test -e upstream/mips && make -C upstream/mips clean
 
-#libwing_Linux := -Lupstream/install/i686-pc-linux-gnu/lib/
-#libwing_Linux +=   upstream/install/i686-pc-linux-gnu/lib/libWINGs.a
-#libwing_Linux +=   upstream/install/i686-pc-linux-gnu/lib/libwraster.a
+libwing_Linux := -Lupstream/install/i686-pc-linux-gnu/lib/
+libwing_Linux +=   upstream/install/i686-pc-linux-gnu/lib/libWINGs.a
+libwing_Linux +=   upstream/install/i686-pc-linux-gnu/lib/libwraster.a
 
 libwing_Solaris := -Lupstream/install/sparc-sun-solaris2.7/lib/
 libwing_Solaris +=   upstream/install/sparc-sun-solaris2.7/lib/libWINGs.a
@@ -51,20 +51,21 @@ target_bin_extension             := $(target_bin_extension_$(platform))
 target_bin                       := ibex.$(target_bin_extension)
 
 jikes_flags        := -nowarn
-gcc_optimizations  := -O2
+gcc_optimizations  := -Os
 #gcc_optimizations  := -O9 -ffast-math -fomit-frame-pointer -foptimize-sibling-calls
 #gcc_optimizations  += -finline-functions -funroll-loops -ffunction-sections -fdata-sections
-
 gcc_flags          := -nostdinc $(gcc_optimizations) -Ibuild/h -Iupstream/jpeg-6b/src -Iupstream/jpeg-6b/build-$(target) -g
 gcc_flags          += -Iupstream/install/lib/gcc-lib/$(target)/3.3/include -Iupstream/install/$(target)/include
+gcc_flags          += -ffunction-sections -fdata-sections -fno-omit-frame-pointer
 gcj                := upstream/install/bin/$(target)-gcj $(gcc_flags) -fCLASSPATH=build/java
+gcj                += -fassume-compiled -fmerge-all-constants -finhibit-reflection
+gcj                += -foptimize-static-class-initialization -feliminate-dwarf2-dups -w
 gcjh               := $(shell pwd)/upstream/install/bin/$(shell test -e upstream/install/bin/$(target)-gcjh && echo $(target)-)gcjh
 g++                := upstream/install/bin/$(target)-gcj $(gcc_flags) -Iupstream/install/include -Wno-multichar
 gcc                := upstream/install/bin/$(target)-gcc $(gcc_flags)
 jar                := $(shell ((type fastjar &>/dev/null) && echo fastjar) || echo jar)
 
 gcj: .install_gcc-3.3_$(target)
-#      make compile
        make build/$(platform)/$(target_bin) link_flags="$(link_flags)" platform=$(platform)
 
 include Makefile.upstream
@@ -80,6 +81,7 @@ java_sources              += build/java/org/xwt/mips/util/SeekableByteArray.java
 java_sources              += build/java/org/xwt/mips/util/SeekableData.java
 java_sources              += build/java/org/xwt/mips/util/SeekableFile.java
 java_sources              += build/java/org/xwt/mips/util/SeekableInputStream.java
+java_classes              := $(java_sources:build/java/%.java=build/class/%.class)
 
 build/java/org/xwt/mips/util/%:
        @test -e .install_mips2java || make .install_mips2java
@@ -97,6 +99,20 @@ build/java/org/xwt/mips/%:
                ln -sf ../../../../../upstream/mips/org/xwt/mips/$*); true
 
 
+### Java Source Files ##############################################################################
+
+.preprocessor: src/org/ibex/util/Preprocessor.java src/org/ibex/util/Vec.java src/gnu/regexp/*.java
+       @mkdir -p build/class/org/ibex/util build/class/gnu/regexp
+       $(gcj) -Isrc -C $^ -d build/class
+       @touch $@
+build/cc/%.cc:     src/%.c    ; @echo linking $@; mkdir -p $(@D); ln -fs `echo $(@D)/ | sed 's_[^/]*//*_../_g'`/$< $@
+build/res/%:       src/%      ; @echo linking $@; mkdir -p $(@D); ln -fs `echo $(@D)/ | sed 's_[^/]*//*_../_g'`/$< $@
+build/java/org/ibex/%.java: src/org/ibex/%.java .preprocessor
+       @echo -e "\n\033[1mpreprocessing      .java -> .java:  $<\033[0m"
+       mkdir -p `dirname $@`; java -cp build/class org.ibex.util.Preprocessor < $^ > $@
+build/java/%.java: src/%.java ; @echo linking $@; mkdir -p $(@D); ln -fs `echo $(@D)/ | sed 's_[^/]*//*_../_g'`/$< $@
+
+
 ### Java Class Files ##############################################################################
 
 build/class/org/ibex/translators/MIPSApps.class: build/mips/mipsapps.mips .jikes
@@ -108,49 +124,14 @@ build/class/org/ibex/translators/MIPSApps.class: build/mips/mipsapps.mips .jikes
        @echo -e "\n\033[1mcompiling          .java -> .class: $<\033[0m"
        ./.jikes -g:none build/java/org/ibex/translators/MIPSApps.java
 
-build/java/org/ibex/%.java: src/org/ibex/%.java
-       make build/class/org/ibex/util/Preprocessor.class
-       @echo -e "\n\033[1mpreprocessing      .java -> .java:  $<\033[0m"
-       mkdir -p `dirname $@`; java -cp build/class org.ibex.util.Preprocessor < $< > $@
-
-build/java/%.java: src/%.java ; @echo linking $@; mkdir -p $(@D); ln -fs `echo $(@D)/ | sed 's_[^/]*//*_../_g'`/$< $@
-build/cc/%.cc:     src/%.c    ; @echo linking $@; mkdir -p $(@D); ln -fs `echo $(@D)/ | sed 's_[^/]*//*_../_g'`/$< $@
-build/res/%:       src/%      ; @echo linking $@; mkdir -p $(@D); ln -fs `echo $(@D)/ | sed 's_[^/]*//*_../_g'`/$< $@
-
-gnu_regexp_jfiles  := $(patsubst src/%.java, build/java/%.java, $(shell find src/gnu/regexp -name \*.java))
-gnu_regexp  := $(patsubst src/%.java, build/class/%.class, $(shell find src/gnu/regexp -name \*.java))
-
-build/class/gnu/regexp/%.class: build/java/gnu/regexp/%.java $(gnu_regexp_jfiles) .jikes
-       @echo -e "\n\033[1mcompiling          .java -> .class: $<\033[0m"
-       mkdir -p build/class/org/ibex/util/
-       ./.jikes $<
-
-build/class/org/ibex/util/Preprocessor.class: src/org/ibex/util/Preprocessor.java $(gnu_regexp) .jikes
-       @echo -e "\n\033[1mcompiling          .java -> .class: $<\033[0m"
-       mkdir -p build/class/org/ibex/util/
-       ./.jikes src/org/ibex/util/Vec.java
-       ./.jikes $<
-
-build/class/%.class: build/java/%.java $(java_sources) .jikes
+compile: .compile
+.compile: .install_mips2java .download_bcel-5.1 $(java_sources) $(java_classes); touch $@
+build/class/%.class: build/java/%.java
        @echo -e "\n\033[1mcompiling          .java -> .class: $<\033[0m"
        mkdir -p $(@D)
-       ./.jikes $<
-
-oldcompile:; CLASSPATH=$$CLASSPATH:lib/libgcj-minimal.jar:upstream/mips/build javac -target 1.1 -source 1.2 -d build/class `find build/java/ -name \*.java`
-
-compile: .jikes .install_mips2java
-       @make -s $(java_sources:build/java/%.java=build/class/%.class)
-.compile: compile
+       $(gcj) -I$(bcel_jar) -C $< -d build/class
 
-.compile: $(java_sources) .jikes .install_mips2java
-       @echo -e "\n\033[1mcompiling          .java -> .class: src/**/*.java\033[0m"
-       @rm -f $(java_sources:build/java/%.java=build/class/%.class)
-       mkdir -p build/class
-       cd build/java; for A in `find . -name \*.java`; do mkdir -p ../class/`dirname $$A`; done
-       @./.jikes $(java_sources)
-       touch .compile
-
-build/JVM/ibex.jar: .compile build/res/builtin.jar build/class/org/ibex/translators/MIPSApps.class
+build/JVM/ibex.jar: build/res/builtin.jar build/class/org/ibex/translators/MIPSApps.class
        @echo -e "\n\033[1marchiving         .class -> .jar:   build/JVM/ibex.jar\033[0m"
        mkdir -p build/JVM
        echo -e "Manifest-Version: 1.0\nMain-Class: org.ibex.Main\n" > build/JVM/.manifest
@@ -160,7 +141,7 @@ build/JVM/ibex.jar: .compile build/res/builtin.jar build/class/org/ibex/translat
                $(patsubst %,../../upstream/mips/build/org/xwt/mips/%*.class, Runtime Registers Syscalls Errno)
 
 
-### GCJH Headers ##############################################################################
+### Headers ##################################################################################
 
 java_headers          := $(java_sources:build/java/%.java=build/h/%.h) 
 build/h/edu/stanford/ejalbert/BrowserLauncher.h:; mkdir -p $(@D); touch $@
@@ -174,15 +155,6 @@ build/h/%.h: build/class/%.class .compile
 ### Native Code ##############################################################################
 
 # a hack since we've disabled gcj's awt implementation
-build/$(platform)/org/ibex/plat/Java2.java.o: ; touch .empty.c; mkdir -p $(@D); $(gcc) -c .empty.c -o $@;
-build/$(platform)/org/ibex/plat/AWT.java.o:   ; touch .empty.c; mkdir -p $(@D); $(gcc) -c .empty.c -o $@;
-
-build/$(platform)/%.java.o: build/class/%.class
-       @echo -e "\n\033[1mcompiling          .java -> .o:     $<\033[0m"
-       mkdir -p `dirname $@`
-       $(gcj) -fCLASSPATH=build/pruned -c $< -o $@
-
-# FIXME detect subclasses of X11
 build/$(platform)/org/ibex/plat/Linux.cc.o: .install_WindowMaker-0.80.2_$(target) 
 build/$(platform)/org/ibex/plat/Solaris.cc.o: .install_WindowMaker-0.80.2_$(target) 
 
@@ -192,129 +164,67 @@ build/$(platform)/org/ibex/plat/$(platform).cc.o: src/org/ibex/plat/$(platform).
        mkdir -p `dirname $@`
        $(g++) -c $< -o $@
 
-nonplat_java_sources := $(filter-out build/java/org/ibex/plat/$(platform).java,$(java_sources))
-build/$(platform)/$(platform).ar: $(nonplat_java_sources:build/java/%.java=build/$(platform)/%.java.o)
-       @echo -e "\n\033[1marchiving             .o -> .a\033[0m"
-       mkdir -p build/$(platform)
-       rm -f $@
-       upstream/install/$(target)/bin/ar rc $@ $^
-       upstream/install/$(target)/bin/ranlib $@
-
-upstream/jpeg-6b/build-$(target)/libjpeg.a: .install_jpeg-6b_$(target)
-
-# note: binaries appear in a different order in the dependency line vs the link line
-build/$(platform)/$(target_bin): upstream/jpeg-6b/build-$(target)/libjpeg.a 
-       @echo -e "\n\033[1mlinking               .o -> $(target_bin)\033[0m"
-       rm -rf build/$(platform)/*
-       make build/$(platform)/org/ibex/plat/$(platform).cc.o
-       make build/$(platform)/builtin.o
-
+libjava_dir := upstream/gcc-3.3/build-$(target)/$(target)/libjava
+nat_libjava_files_ := boehm.o exception.o posix-threads.o posix.o prims.o resolve.o java/net/natInetAddress.o
+nat_libjava_files_ += java/net/natPlainSocketImpl.o java/io/natFile*.o java/util/zip/nat*.o gnu/gcj/runtime/natFirstThread.o
+nat_libjava_files_ += gnu/gcj/runtime/natNameFinder.o gnu/gcj/runtime/natStackTrace.o gnu/gcj/runtime/natSharedLibLoader.o
+nat_libjava_files_ += gnu/gcj/runtime/natStringBuffer.o gnu/gcj/runtime/natVMClassLoader.o gnu/gcj/runtime/natFinalizerThread.o
+nat_libjava_files_ += $(shell cd $(libjava_dir) 2>/dev/null; find java/lang -name \*.o -not -name '*[A-Z]*' 2>/dev/null)
+nat_libjava_files_ += $(shell cd $(libjava_dir) 2>/dev/null; find java/lang -name nat\*.o 2>/dev/null)
+nat_libjava_files := $(nat_libjava_files_:%=$(libjava_dir)/%)
+
+.natcalls-$(platform): $(nat_libjava_files)
+       @echo -e "\n\033[1mdetecting CNI calls...\033[0m"
+       rm -f build/$(platform)/natibex.a
        cd upstream/gcc-3.3/build-$(target)/$(target)/libjava;           \
-                       (find . -name nat\*.o | grep -v JIS;              \
-                       echo boehm.o;\
-                       echo defineclass.o;\
-                       echo exception.o;\
-                       echo posix-threads.o;\
-                       echo posix.o;\
-                       echo prims.o;\
-                       echo jni.o;\
-                       echo resolve.o;\
-                       echo libltdl/ltdl.o;\
-                       find java gnu -name \*.o -not -name '*[A-Z]*';         \
-                       ) > $(shell pwd)/.natbins
-
-
-       cd upstream/gcc-3.3/build-$(target)/$(target)/libjava;\
-       (cat $(shell pwd)/.natbins; echo $(shell pwd)/build/$(platform)/org/ibex/plat/$(platform).cc.o) |\
-               grep -v shs | grep -v SHS |xargs nm |\
+               $(shell pwd)/upstream/install/$(target)/bin/ar cq        \
+                       $(shell pwd)/build/$(platform)/natibex.a         \
+                       $<
+       nm build/$(platform)/natibex.a |\
                grep _ZN | c++filt --format java | grep " U " | sed 's_\.class\$$_.class_' | sed 's_ * U __' | sed 's_(.*__' \
-               > $(shell pwd)/.natcalls
+               > $(shell pwd)/$@
 
-       rm -rf build/pruned; mkdir -p build/pruned
-       javac -classpath lib/bcel-5.1.jar:build/class -d build/class src/org/ibex/util/BytecodePruner.java
-       rm -f build/$(platform)/ibex.jar
+bcel_jar := upstream/bcel-5.1/src/bcel-5.1.jar
+build/$(platform)/ibex.pruned.jar: .compile .install_jpeg-6b_$(target) build/$(platform)/builtin.o .natcalls-$(platform)
+       @echo -e "\n\033[1mpruning              .jar -> .jar\033[0m"
+       cp upstream/install/share/java/libgcj-3.3.jar build/$(platform)/ibex.jar
        cd build/class; \
-               fastjar cf ../$(platform)/ibex.jar \
+               jar uf ../$(platform)/ibex.jar \
                        `find . -name \*.class | grep -v ibex/plat/` \
                        org/ibex/plat/$(platform)*.class \
                        org/ibex/plat/X11*.class \
                        org/ibex/plat/GCJ*.class \
                        org/ibex/plat/POSIX*.class
-       java -cp lib/bcel-5.1.jar:build/class org.ibex.util.BytecodePruner \
-               build/$(platform)/ibex.jar:upstream/install/share/java/libgcj-3.3.jar \
-               -o build/pruned \
-               `cat .natcalls`
-
-       rm build/pruned/org/ibex/plat/GCJ*.class
-       cp build/java/org/ibex/plat/GCJ.java build/pruned/org/ibex/plat/
-       cp upstream/gcc-3.3/build-$(target)/$(target)/libjava/java/lang/Object.class build/pruned/java/lang/
-
-       rm -f build/pruned/java/lang/System*.*
-       cp upstream/gcc-3.3/src/libjava/java/lang/System.java build/pruned/java/lang/
-
-       cd build/pruned;                                                  \
-               for A in `find gnu/gcj java/lang java/net -name \*.class -or -name \*.java`; do    \
-                       echo compiling $$A....;                           \
-                       ../../upstream/install/bin/$(target)-gcj          \
-                               -w -c -Os \
-                               -fCLASSPATH=../../build/$(platform)/ibex.jar \
-                               $$A &&                     \
-                               (mkdir -p ../../build/$(platform)/`dirname $$A`; mv *.o ../../build/$(platform)/`dirname $$A`); \
-               done
-
-#                              -fassume-compiled          \
-       cd build/pruned; rm -rf gnu/gcj java/lang java/net
-       cd build/pruned;                                                  \
-               for A in `find . -name \*.class -or -name \*.java`; do    \
-                       echo compiling $$A....;                           \
-                       ../../upstream/install/bin/$(target)-gcj          \
-                               -w -c -Os \
-                               -fCLASSPATH=../../build/$(platform)/ibex.jar \
-                               $$A &&                     \
-                               (mkdir -p ../../build/$(platform)/`dirname $$A`; mv *.o ../../build/$(platform)/`dirname $$A`); \
-               done
-#                              -fassume-compiled          \
-#                              -finhibit-reflection          \
-#                              -fnew-ra \
-#                              -ffunction-sections \
-#                              -fdata-sections \
-#                              -fomit-frame-pointer \
-#                              -fno-force-mem \
-#                              -fno-force-addr \
-#                              -fmerge-all-constants \
-
-       rm -f build/$(platform)/ibex.a
+       java -cp $(bcel_jar):build/class org.ibex.util.NanoGoat build/$(platform)/ibex.jar `cat .natcalls-$(platform)`
+       mv build/$(platform)/ibex.jar.pruned $@
 
-       cd upstream/gcc-3.3/build-$(target)/$(target)/libjava;           \
-               $(shell pwd)/upstream/install/$(target)/bin/ar cq        \
-                       $(shell pwd)/build/$(platform)/ibex.a            \
-                       `find $(shell pwd)/build/$(platform) -name \*.o`
+build/$(platform)/$(target_bin): build/$(platform)/ibex.pruned.jar .natcalls-$(platform)
 
-       rm -f build/$(platform)/natibex.a
-       cd upstream/gcc-3.3/build-$(target)/$(target)/libjava;           \
-               $(shell pwd)/upstream/install/$(target)/bin/ar cq        \
-                       $(shell pwd)/build/$(platform)/natibex.a         \
-                       `cat $(shell pwd)/.natbins`
-       PATH=upstream/install/bin:$$PATH upstream/install/bin/$(target)-gcj          \
-               -Wl,-O2,--relax,--gc-sections,--noinhibit-exec                       \
+       @echo -e "\n\033[1mcompiling              .jar -> .o\033[0m"
+       $(gcj) -c --bootclasspath=build/$(platform)/ibex.jar -d build/$(platform) build/$(platform)/ibex.pruned.jar
+
+       @echo -e "\n\033[1mlinking              .o -> $(target_bin).phat\033[0m"
+       PATH=upstream/install/bin:$$PATH $(gcj) \
+               -Wl,-O2,--relax,--gc-sections,--noinhibit-exec,--no-whole-archive    \
                --main=org.ibex.plat.$(platform)                                     \
                -Dfile.encoding=UTF8                                                 \
-               -Lupstream/install/$(target)/lib                                     \
-               -Lupstream/install/lib                                               \
+               -Lupstream/install/$(target)/lib -Lupstream/install/lib              \
                -Os -w                                                               \
-               -Wl,--whole-archive                                                  \
-               build/$(platform)/ibex.a                                             \
-               -Wl,--no-whole-archive,--gc-sections                                 \
+               `find build/$(platform) -name \*.o`                                  \
                build/$(platform)/natibex.a                                          \
                upstream/jpeg-6b/build-$(target)/libjpeg.a                           \
                $(link_flags)                                                        \
-               upstream/gcc-3.3/build-$(target)/$(target)/boehm-gc/.libs/libgcjgc.a \
-               -lz -ldl                                                             \
-               -o $@
-#      strip build/Linux/ibex.linux
-#      ls -l build/Linux/ibex.linux
-#      upx-ucl-beta --best build/Linux/ibex.linux
-#      ls -l build/Linux/ibex.linux
+               $(libjava_dir)/../boehm-gc/.libs/libgcjgc.a                          \
+               -o $@.phat
+       @echo; ls -l $@.phat
+
+       @echo -e "\n\033[1mstripping              $(target_bin).phat -> $(target_bin)\033[0m"
+       strip $@.phat -o $@
+       @echo; ls -l $@.phat
+
+       @echo -e "\n\033[1mcompressing              $(target_bin) -> $(target_bin)\033[0m"
+       upx-ucl-beta $@
+       @echo; ls -l $@.phat
 
 
 ### Builtin Resources ##############################################################################
@@ -328,9 +238,9 @@ build/res/fonts/vera: .download_vera-1.10
 build/res/builtin.jar: $(builtin_src:src/%=build/res/%) build/res/fonts/vera
        @echo -e "\n\033[1mzipping            res/* -> .jar: builtin.jar\033[0m"
        cd build/res; $(jar) cf builtin.jar org/ibex/builtin/scar.png
-#      cd build/res; $(jar) cf builtin.jar $(^:build/res/%=%)
 build/$(platform)/builtin.o: build/res/builtin.jar
        @echo -e "\n\033[1mwrapping            .jar -> .o: resources.o\033[0m"
+       @mkdir -p $(@D)
        @(echo "unsigned int builtin_length = ";                                \
                (wc -c build/res/builtin.jar | sed "s_build.*__");              \
                echo \;;                                                        \
@@ -339,7 +249,6 @@ build/$(platform)/builtin.o: build/res/builtin.jar
                echo "};") > .builtin.c
        $(gcc) -c .builtin.c -o build/$(platform)/builtin.o
 
-
 build/mips/%.c.o: src/%.c .download_libmspack-20030726
        make .install_freetype-2.1.4_mips-unknown-elf target=mips-unknown-elf
        make .install_libmspack-20030726_mips-unknown-elf target=mips-unknown-elf
@@ -372,8 +281,8 @@ build/mips/mipsapps.mips: build/mips/org/ibex/translators/Freetype.c.o build/mip
 ### Maintainer ######################################################################################
 
 current_build         := $(shell cat next.build)
-strip_$(platform) := upstream/install/$(target)/bin/strip build/$(platform)/$(target_bin) -o 
-strip_JVM       := cp build/$(platform)/$(target_bin)
+strip_$(platform)     := upstream/install/$(target)/bin/strip build/$(platform)/$(target_bin) -o 
+strip_JVM             := cp build/$(platform)/$(target_bin)
 install-dist:;     $(strip_$(platform)) /var/www/org/xwt/dist/master/ibex-$(current_build).$(target_bin_extension).unsigned
 dist: compile
        (echo -n 0000; (echo "10k16o16i"; cat next.build | tr a-z A-Z; echo "1+f") | dc) | tail --bytes=5 > next.build-
index 67b8655..ab40478 100644 (file)
@@ -17,7 +17,7 @@ url_jikes-1.18         := http://dist.ibex.org/jikes-1.18.tgz
 url_libmspack-20030726 := http://www.kyz.uklinux.net/downloads/libmspack-20030726.tar.gz
 url_vera-1.10          := http://ftp.gnome.org/pub/GNOME/sources/ttf-bitstream-vera/1.10/ttf-bitstream-vera-1.10.tar.gz
 url_WindowMaker-0.80.2 := http://windowmaker.org/pub/source/release/WindowMaker-0.80.2.tar.gz
-url_bcel-5.1           := http://apache.130th.net/jakarta/bcel/binaries/bcel-5.1.tar.gz
+url_bcel-5.1           := http://apache.webmeta.com/jakarta/bcel/binaries/bcel-5.1.tar.gz
 
 .install_binutils-2.13.2.1_powerpc-apple-darwin: .vendor
        rm -rf upstream/darwin-linker/src
@@ -83,6 +83,7 @@ configure_WindowMaker-0.80.2_$(target)  += --host=i686-pc-linux-gnu --x-librarie
 # libjpeg's configury doesn't obey --target
 environment_jpeg-6b_$(target)           += PATH=$(shell pwd)/upstream/install/$(target)/bin:$$PATH
 environment_jpeg-6b_$(target)           += CC=$(shell pwd)/upstream/install/bin/$(target)-gcc
+environment_jpeg-6b_$(target)           += CFLAGS="-Os -ffunction-sections -fdata-sections -I ."
 environment_jpeg-6b_$(target)           += AR="$(shell pwd)/upstream/install/$(target)/bin/ar rc"
 environment_jpeg-6b_$(target)           += AR2=$(shell pwd)/upstream/install/$(target)/bin/ranlib
 
diff --git a/jode.conf b/jode.conf
deleted file mode 100644 (file)
index 86575cf..0000000
--- a/jode.conf
+++ /dev/null
@@ -1,40 +0,0 @@
-classpath = "build/","upstream/install/share/java/libgcj-3.3.jar","build/class"
-dest = "out"
-strip = "unreach","lvt"
-#,"inner"
-
-#renamer = new UniqueRenamer
-
-load = new WildCard { value = "org.ibex.*" },
-       new WildCard { value = "gnu.*" },
-       new WildCard { value = "org.bouncycastle.*" },
-       new WildCard { value = "edu.*" },
-       new WildCard { value = "java.*" }
-
-preserve = new WildCard { value = "org.ibex.Main" },
-           new WildCard { value = "org.ibex.plat.Linux" },
-           new WildCard { value="java.lang" },
-           new WildCard { value="gnu.gcj.protocol" },
-           new WildCard { value="java.net.URLConnection" },
-           new WildCard { value="gnu.gcj.protocol.file.Connection" },
-           new WildCard { value="gnu.gcj.protocol.http.Connection" },
-           new WildCard { value="gnu.gcj.protocol.jar.Connection" },
-           new WildCard { value="gnu.gcj.protocol.core.Connection" },
-           new WildCard { value="java.net.JarURLConnection" },
-           new WildCard { value="java.net.HttpURLConection" },
-           new WildCard { value="java.security.Policy" }
-#           new MultiIdentifierMatcher { 
-#               and = new WildCard { value = "org.myorg.publiclib.*" },
-#                   new ModifierMatcher { access = "PUBLIC" }
-#         }
-
-analyzer = new ConstantAnalyzer
-
-# The LocalOptimizer will reorder local variables to use fewer slots.
-# It may still have some bugs, so remove it if your applet doesn't
-# work (and send me the class).
-# The RemovePopAnalyzer will remove instructions that were optimized
-# away by the ConstantAnalyzer and LocalOptimizer.
-#post = new RemovePopAnalyzer
-
-
diff --git a/lib/libgcj-minimal.jar b/lib/libgcj-minimal.jar
deleted file mode 100644 (file)
index 0276160..0000000
Binary files a/lib/libgcj-minimal.jar and /dev/null differ
index 7f6f248..10da62b 100644 (file)
@@ -41,7 +41,7 @@ public class HTTP {
     // Instance Data ///////////////////////////////////////////////////////////////////////////////////////////////
 
     final String originalUrl;              ///< the URL as passed to the original constructor; this is never changed
-    URL url = null;                        ///< the URL to connect to; this is munged when the url is parsed */
+    String url = null;                     ///< the URL to connect to; this is munged when the url is parsed */
     String host = null;                    ///< the host to connect to
     int port = -1;                         ///< the port to connect on
     boolean ssl = false;                   ///< true if SSL (HTTPS) should be used
@@ -270,7 +270,7 @@ public class HTTP {
         if (Log.verbose) Log.info(this, "evaluating PAC script");
         String pac = null;
         try {
-            Object obj = pacFunc.call(url.toString(), url.getHost(), null, null, 2);
+            Object obj = pacFunc.call(url, host, null, null, 2);
             if (Log.verbose) Log.info(this, "  PAC script returned \"" + obj + "\"");
             pac = obj.toString();
         } catch (Throwable e) {
@@ -322,18 +322,22 @@ public class HTTP {
         }
 
         if (url.startsWith("https:")) {
-            this.url = new URL("http" + url.substring(5));
             ssl = true;
         } else if (!url.startsWith("http:")) {
-            throw new MalformedURLException("HTTP only supports http/https urls");
+            throw new IOException("HTTP only supports http/https urls");
+        }
+        if (url.indexOf("://") == -1) throw new IOException("URLs must contain a ://");
+        String temphost = url.substring(url.indexOf("://") + 1);
+        path = temphost.substring(temphost.indexOf('/'));
+        temphost = temphost.substring(0, temphost.indexOf('/'));
+        if (temphost.indexOf(':') != -1) {
+            port = Integer.parseInt(temphost.substring(temphost.indexOf(':')+1));
+            temphost = temphost.substring(0, temphost.indexOf(':'));
         } else {
-            this.url = new URL(url);
+            port = ssl ? 443 : 80;
         }
-        if (!skipResolveCheck) resolveAndCheckIfFirewalled(this.url.getHost());
-        port = this.url.getPort();
-        path = this.url.getFile();
-        if (port == -1) port = ssl ? 443 : 80;
-        host = this.url.getHost();
+        if (!skipResolveCheck) resolveAndCheckIfFirewalled(temphost);
+        host = temphost;
         if (Log.verbose) Log.info(this, "creating HTTP object for connection to " + host + ":" + port);
 
         Proxy pi = Platform.detectProxy();
index c3bba86..4b110a6 100644 (file)
@@ -229,6 +229,8 @@ public abstract class Platform {
             return;
         }
         // check the URL for well-formedness, as a defense against buffer overflow attacks
+        // FIXME check URL without using URL class
+        /*
         try {
             String u = url;
             if (u.startsWith("https")) u = "http" + u.substring(5);
@@ -237,6 +239,7 @@ public abstract class Platform {
             Log.info(Platform.class, "URL " + url + " is not well-formed");
             Log.info(Platform.class, e);
         }
+        */
         Log.info(Platform.class, "newBrowserWindow, url = " + url);
         platform._newBrowserWindow(url);
     }
index 59b48c3..6cbaf23 100644 (file)
@@ -367,7 +367,7 @@ class Interpreter implements ByteCodes, Tokens {
 
             case THROW:
                 throw new JSExn(stack.pop());
-
+                /* FIXME
             case MAKE_GRAMMAR: {
                 final Grammar r = (Grammar)arg;
                 final JSScope final_scope = scope;
@@ -389,7 +389,7 @@ class Interpreter implements ByteCodes, Tokens {
                 stack.push(r2);
                 break;
             }
-
+                */
             case ADD_TRAP: case DEL_TRAP: {
                 Object val = stack.pop();
                 Object key = stack.pop();
index 932c5b8..09f50db 100644 (file)
@@ -317,7 +317,7 @@ class Parser extends Lexer implements ByteCodes {
         // attempt to continue the expression
         continueExpr(b, minPrecedence);
     }
-
+    /*
     private Grammar parseGrammar(Grammar g) throws IOException {
         int tok = getToken();
         if (g != null)
@@ -348,7 +348,7 @@ class Parser extends Lexer implements ByteCodes {
         if (g == null) return parseGrammar(g0);
         return parseGrammar(new Grammar.Juxtaposition(g, g0));
     }
-
+    */
     /**
      *  Assuming that a complete assignable (lvalue) has just been
      *  parsed and the object and key are on the stack,
@@ -368,7 +368,7 @@ class Parser extends Lexer implements ByteCodes {
             // force the default case
             tok = -1;
         switch(tok) {
-
+            /*
         case GRAMMAR: {
             b.add(parserLine, GET_PRESERVE);
             Grammar g = parseGrammar(null);
@@ -382,7 +382,7 @@ class Parser extends Lexer implements ByteCodes {
             b.add(parserLine, PUT);
             break;
         }
-
+            */
         case ASSIGN_BITOR: case ASSIGN_BITXOR: case ASSIGN_BITAND: case ASSIGN_LSH: case ASSIGN_RSH: case ASSIGN_URSH:
         case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_ADD: case ASSIGN_SUB: case ADD_TRAP: case DEL_TRAP: {
             if (tok != ADD_TRAP && tok != DEL_TRAP) b.add(parserLine, GET_PRESERVE);
index e62a9ba..e96c23c 100644 (file)
@@ -9,16 +9,14 @@ extern int _Jv_argc;
 
 void org::ibex::plat::Linux::fixEnvironment() {
   // this wreaks havoc on gdb
-  /*
-    // see http://lists.debian.org/debian-glibc/2003/debian-glibc-200311/msg00647.html
-    const char* ld_assume_kernel = getenv("LD_ASSUME_KERNEL");
-    if (ld_assume_kernel == NULL || strcmp("2.4.1", ld_assume_kernel)) {
-        int result;
-        printf("respawning self (%s) with LD_ASSUME_KERNEL=2.4.1\n", _Jv_argv[0]);
-        setenv("LD_ASSUME_KERNEL", "2.4.1", 1);
-        result = execvp(_Jv_argv[0], (char* const*)((void*)_Jv_argv));
-        printf("execvp() failed with error code %d\n", result);
-       exit(-1);
-    }
-  */
+  // see http://lists.debian.org/debian-glibc/2003/debian-glibc-200311/msg00647.html
+  const char* ld_assume_kernel = getenv("LD_ASSUME_KERNEL");
+  if (ld_assume_kernel == NULL || strcmp("2.4.1", ld_assume_kernel)) {
+    int result;
+    printf("respawning self (%s) with LD_ASSUME_KERNEL=2.4.1\n", _Jv_argv[0]);
+    setenv("LD_ASSUME_KERNEL", "2.4.1", 1);
+    result = execvp(_Jv_argv[0], (char* const*)((void*)_Jv_argv));
+    printf("execvp() failed with error code %d\n", result);
+    exit(-1);
+  }
 }
index 53e20de..680fb1e 100644 (file)
@@ -747,7 +747,6 @@ void org::ibex::plat::X11::natInit() {
     // FIXME: don't know why (True, False) is the best solution...
     if(XmuLookupStandardColormap(display, screen_num, visual->visualid, colorDepth, XA_RGB_BEST_MAP, True, False) == 0)
         org::ibex::Platform::criticalAbort(JvNewStringLatin1("ERROR: XmuLookupStandardColormap failed"));
-    
     XStandardColormap* best_map_info = NULL;
     int count;
     if (XGetRGBColormaps(display, RootWindow(display, screen_num), &best_map_info, &count, XA_RGB_BEST_MAP) == 0)
@@ -769,9 +768,8 @@ void org::ibex::plat::X11::natInit() {
     org::ibex::util::Log::info(this->getClass(), JvNewStringLatin1(buf));
 }
 
-//#include "WINGs/WINGs.h"
+#include "WINGs/WINGs.h"
 jstring org::ibex::plat::X11::_fileDialog(jstring suggestedFileName, jboolean write) {
-#ifdef asfasdfasf
   int argc = 1;
   char* argv[2];
   argv[0] = "Ibex";
@@ -794,11 +792,9 @@ jstring org::ibex::plat::X11::_fileDialog(jstring suggestedFileName, jboolean wr
     if (WMRunModalFilePanelForDirectory(oPanel, NULL, buf, /*title*/ NULL, NULL) != True) return NULL;
     return JvNewStringLatin1(WMGetFilePanelFileName(oPanel));
   }
-#endif
   return NULL;
 }
 
-
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
@@ -2334,3 +2330,4 @@ XmuDeleteStandardColormap(Display *dpy, int screen, Atom property)
         }
 }
 
+
similarity index 64%
rename from src/org/ibex/util/BytecodePruner.java
rename to src/org/ibex/util/NanoGoat.java
index a61c84d..7f1a50e 100644 (file)
@@ -7,16 +7,19 @@ import org.apache.bcel.generic.*;
 import org.apache.bcel.classfile.*;
 import org.apache.bcel.util.*;
 
-public class BytecodePruner {
+public class NanoGoat {
 
     public static final boolean deleteMethods = false;
     public static SyntheticRepository repo = null;
     public static HashSet dest = new HashSet();
+    public static HashSet constructed = new HashSet();
     public static String outdir = ".";
     public static Hashtable subclasses = new Hashtable();
+    public static Hashtable uponconstruction = new Hashtable();
+    public static Hashtable mark_if_constructed = new Hashtable();
     public static int level = 0;
 
-    public BytecodePruner() { }
+    public NanoGoat() { }
 
     public void loadAllMethods(String classname) throws Exception {
         visitJavaClass(repo.loadClass(classname));
@@ -25,16 +28,13 @@ public class BytecodePruner {
             visitJavaMethod(repo.loadClass(classname), meths[i]);
     }
 
-    public void loadField(String classAndMethodName) throws Exception {
-        String classname = classAndMethodName.substring(0, classAndMethodName.lastIndexOf('.'));
-        String methodname = classAndMethodName.substring(classAndMethodName.lastIndexOf('.') + 1);
+    public void loadAllStaticMethods(String classname) throws Exception {
         visitJavaClass(repo.loadClass(classname));
-        Field[] meths = repo.loadClass(classname).getFields();
+        Method[] meths = getMethods(repo.loadClass(classname));
         for(int i=0; i<meths.length; i++)
-            if (meths[i].getName().equals(methodname))
-                visitJavaField(meths[i]);
+            if (meths[i].isStatic())
+                visitJavaMethod(repo.loadClass(classname), meths[i]);
     }
-    
 
     public void loadMethod(String classAndMethodName) throws Exception {
         String classname = classAndMethodName.substring(0, classAndMethodName.lastIndexOf('.'));
@@ -48,10 +48,9 @@ public class BytecodePruner {
     }
     public static void main(String[] s) throws Exception {
         int start = 1;
-        if (s.length >= 3 && s[1].equals("-o")) { outdir = s[2]; start += 2; }
         repo = SyntheticRepository.getInstance(new ClassPath(s[0]));
 
-        BytecodePruner bcp = new BytecodePruner();
+        NanoGoat bcp = new NanoGoat();
         for(int i=start; i<s.length; i++) {
             try {
                 if (s[i].endsWith(".class")) {
@@ -60,9 +59,15 @@ public class BytecodePruner {
                     JavaClass cl = repo.loadClass(s[i].substring(0, s[i].lastIndexOf('.')));;
                     bcp.visitJavaClass(cl);
                     bcp.loadMethod(s[i]);
+                    Field[] fields = cl.getFields();
+                    for(int j=0; j<fields.length; j++) {
+                        if (fields[j].getName().equals(s[i].substring(s[i].lastIndexOf('.') + 1)))
+                            bcp.visitJavaField(fields[j], cl);
+                    }
                 }
             } catch (Exception e) {
                 System.out.println("WARNING: couldn't load class for " + s[i]);
+                e.printStackTrace();
             }
         }
 
@@ -72,23 +77,36 @@ public class BytecodePruner {
         bcp.loadMethod("java.lang.Thread.run");
         bcp.loadAllMethods("java.lang.SecurityContext");
         bcp.loadAllMethods("java.lang.ThreadDeath");
+        bcp.loadMethod("java.lang.Thread.run");                  // we call start(), but the VM calls run()...
+        bcp.loadMethod("java.lang.ref.Reference.enqueue");       // the GC calls this directly
+        bcp.loadAllMethods("gnu.gcj.runtime.StringBuffer");      // the compiler emits calls directly to this class
+        bcp.loadAllMethods("gnu.gcj.convert.Input_UTF8");        // retrieved via reflection
+        bcp.loadAllMethods("gnu.gcj.convert.Output_UTF8");       // retrieved via reflection
+        bcp.loadMethod("gnu.gcj.convert.BytesToUnicode.done");   // called by natString
+        bcp.loadAllStaticMethods("java.lang.reflect.Modifier");        // used all over natClass...
+
+        // the Interpreter.run() method's switchblock is too complex...
+        bcp.loadAllMethods("org.ibex.js.Interpreter$TryMarker");
+        bcp.loadAllMethods("org.ibex.js.Interpreter$CatchMarker");
+        bcp.loadAllMethods("org.ibex.js.Interpreter$LoopMarker");
+        bcp.loadAllMethods("org.ibex.js.Interpreter$FinallyData");
+        bcp.loadAllMethods("org.ibex.js.Interpreter$CallMarker");
+        bcp.loadAllMethods("org.ibex.js.Interpreter");
+        bcp.loadAllMethods("org.ibex.js.Interpreter$1");
+        bcp.loadAllMethods("org.ibex.js.Interpreter$Stub");
+        bcp.loadAllMethods("org.ibex.js.Trap$TrapScope");
+        bcp.loadMethod("org.ibex.js.JSScope.top");
+        bcp.loadAllMethods("org.ibex.Picture$1");
+        bcp.loadAllMethods("org.ibex.Ibex$Blessing");
+        bcp.loadAllMethods("org.ibex.util.SSL$entropySpinner");
+        bcp.loadAllMethods("org.ibex.HTTP$HTTPInputStream");
+        bcp.visitJavaClass(repo.loadClass("org.ibex.util.SSL"));
 
         bcp.loadAllMethods("java.util.Hashtable$HashIterator");
         bcp.loadMethod("java.util.SimpleTimeZone.useDaylightTime");
         bcp.visitJavaClass(repo.loadClass("gnu.gcj.runtime.FinalizerThread"));
         bcp.visitJavaClass(repo.loadClass("gnu.gcj.runtime.FirstThread"));
 
-        bcp.loadMethod("java.lang.Thread.run");                // we call start(), but the VM calls run()...
-        bcp.loadMethod("java.lang.ref.Reference.enqueue");     // the GC calls this directly
-        bcp.loadAllMethods("gnu.gcj.runtime.StringBuffer");    // the compiler emits calls directly to this class
-        bcp.loadAllMethods("gnu.gcj.convert.Input_UTF8");      // retrieved via reflection
-        bcp.loadAllMethods("gnu.gcj.convert.Output_UTF8");     // retrieved via reflection
-
-        bcp.loadAllMethods("gnu.gcj.protocol.http.Handler");
-        bcp.loadAllMethods("gnu.gcj.protocol.file.Handler");
-        bcp.loadAllMethods("gnu.gcj.protocol.core.Handler");
-        bcp.loadAllMethods("gnu.gcj.protocol.jar.Handler");
-
         // to ensure we get all the stuff that might be called from CNI
         bcp.loadAllMethods("org.ibex.plat.Linux");
         bcp.loadAllMethods("org.ibex.plat.X11");
@@ -106,21 +124,23 @@ public class BytecodePruner {
         System.out.println();
 
         System.out.println("Dumping...");
-        StringTokenizer st = new StringTokenizer(s[0], ":");
-        while(st.hasMoreTokens()) {
-            ZipFile zf = new ZipFile(st.nextToken());
-            Enumeration e = zf.entries();
-            while(e.hasMoreElements()) {
-                String ss = ((ZipEntry)e.nextElement()).getName();
-                if (!ss.endsWith(".class")) continue;
-                ss = ss.substring(0, ss.length() - 6);
-                ss = ss.replace('/', '.');
-                dump(repo.loadClass(ss));
-            }
+        ZipFile zf = new ZipFile(s[0]);
+        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(s[0] + ".tmp"));
+        Enumeration e = zf.entries();
+        while(e.hasMoreElements()) {
+            ZipEntry ze = ((ZipEntry)e.nextElement());
+            String ss = ze.getName();
+            if (!ss.endsWith(".class")) continue;
+            ss = ss.substring(0, ss.length() - 6);
+            ss = ss.replace('/', '.');
+            dump(repo.loadClass(ss), zos);
         }
+        zos.close();
+        zf.close();
+        new File(s[0] + ".tmp").renameTo(new File(s[0] + ".pruned"));
     }
 
-    public static void dump(JavaClass clazz) throws Exception {
+    public static void dump(JavaClass clazz, ZipOutputStream zos) throws Exception {
         if (!dest.contains(clazz)) return;
 
         ConstantPoolGen newcpg = new ConstantPoolGen(clazz.getConstantPool());
@@ -130,40 +150,35 @@ public class BytecodePruner {
         cg.setMinor(0);
         cg.setConstantPool(newcpg);
 
-        boolean constructed = false;
+        boolean isconstructed = false;
         Method[] methods = getMethods(clazz);
         for(int i=0; i<methods.length; i++)
             if (dest.contains(methods[i]) && methods[i].getName().equals("<init>"))
-                constructed = true;
+                isconstructed = true;
 
         // we can only prune static fields (to avoid altering object layout, which is hardcoded into
         // CNI code), but that's okay since instance fields don't contribute to binary size
         Field[] fields = clazz.getFields();
         for(int i=0; i<fields.length; i++) {
-            if (!dest.contains(fields[i]) && fields[i].isStatic()) { 
+            if ((!dest.contains(fields[i]) && fields[i].isStatic()) ||
+                ((!(constructed.contains(clazz))) && !fields[i].isStatic())) { 
                 System.out.println("  pruning field " + clazz.getClassName() + "." + fields[i].getName());
-                cg.removeField(fields[i]);
-            }
-            /*  -- there's really no point to this --
-            if (!constructed && !fields[i].isStatic()) {
-                System.out.println("  unconstructed: pruning field " + clazz.getClassName() + "." + fields[i].getName());
-                cg.removeField(fields[i]);
+                // FIXME this confuses gcj in jar-at-a-time mode
+                //cg.removeField(fields[i]);
             }
-            */
         }
 
         int numMethods = 0;
         boolean good = false;
         for(int i=0; i<methods.length; i++) {
-            if (dest.contains(methods[i]) && (constructed || !methods[i].isStatic())) {
-                if (!methods[i].getName().equals("<clinit>")) good = true;
+            if (dest.contains(methods[i]) && (isconstructed || methods[i].isStatic())) {
+                good = true;
             } else {
                 if (methods[i].getCode() == null) {
                     System.out.println("  empty codeblock: " + clazz.getClassName() + "." + methods[i].getName());
                 } else {
-                    System.out.println("  pruning " +(constructed?"":"unconstructed")+ " method " +
+                    System.out.println("  pruning " +(isconstructed?"":"unconstructed")+ " method " +
                                        clazz.getClassName() + "." + methods[i].getName());
-                    // FIXME: try deleteMethods
                     if (deleteMethods) { cg.removeMethod(methods[i]); continue; }
                     MethodGen mg = new MethodGen(methods[i], clazz.getClassName(), newcpg);
                     mg.removeExceptions();
@@ -186,7 +201,12 @@ public class BytecodePruner {
             }
         }
 
-        if (!good) {
+        // FIXME: chain up to superclass' <clinit>... that might remove the need for this hack
+        // FIXME: gcj compiling in jar-at-a-time mode can't be convinced to let classes outside the jar override
+        //        the ones inside the jar
+        good = true;
+
+        if (!good && !clazz.isAbstract() && !clazz.isInterface()) {
             System.out.println("DROPPING " + clazz.getClassName());
             JavaClass[] ifaces = clazz.getInterfaces();
             String[] ifacestrings = new String[ifaces.length];
@@ -200,8 +220,10 @@ public class BytecodePruner {
         } else {
             System.out.println("dumping " + clazz.getClassName());
         }
-        new File(outdir + "/" + new File(clazz.getClassName().replace('.', '/')).getParent()).mkdirs();
-        cg.getJavaClass().dump(outdir + "/" + clazz.getClassName().replace('.', '/') + ".class");
+        FilterOutputStream noclose = new FilterOutputStream(zos) { public void close() throws IOException { flush(); } };
+        zos.putNextEntry(new ZipEntry(clazz.getClassName().replace('.', '/')+".class"));
+        cg.getJavaClass().dump(noclose);
+        noclose.flush();
     }
 
     public JavaClass sig2class(String sig) throws Exception {
@@ -245,38 +267,73 @@ public class BytecodePruner {
         visitJavaClass(jc);
         if (jc.getClassName().indexOf("SharedLib") != -1) return;
         if (jc.getClassName().indexOf("Datagram") != -1) return;
+        if (jc.getClassName().startsWith("java.io.Object")) return;
+        if (jc.getClassName().startsWith("java.util.jar.")) return;
+        if (jc.getClassName().startsWith("java.net.Inet6")) return;
 
         // gcj bug; gcj can't compile this method from a .class file input; I have no idea why
         if (jc.getClassName().equals("java.lang.System") && method.getName().equals("runFinalizersOnExit")) return;
 
+        // we know these can't be constructed
+        if (method.getName().equals("<init>") && jc.getClassName().startsWith("java.lang.reflect.")) return;
+
         if (dest.contains(method)) return;
         dest.add(method);
 
-        if (method.isStatic()) loadMethod(jc.getClassName() + ".<clinit>");
+        if (method.getName().equals("<clinit>") && jc.getSuperClass() != null)
+            loadMethod(jc.getSuperClass().getClassName() + ".<clinit>");
+
+        if (method.isStatic() || method.getName().equals("<init>")) loadMethod(jc.getClassName() + ".<clinit>");
+        if (method.getName().equals("<init>")) {
+            // FIXME: generalize to all perinstancemethods
+            constructed.add(jc);
+            HashSet hs = (HashSet)uponconstruction.get(jc);
+            if (hs != null) {
+                Iterator it = hs.iterator();
+                while(it.hasNext()) visitJavaMethod(jc, (Method)it.next());
+            }
+            loadMethod(jc.getClassName() + ".equals");
+            loadMethod(jc.getClassName() + ".hashCode");
+            loadMethod(jc.getClassName() + ".toString");
+            loadMethod(jc.getClassName() + ".finalize");
+            loadMethod(jc.getClassName() + ".clone");
+        }
+
+        ConstantPoolGen cpg = new ConstantPoolGen(method.getConstantPool());
+        if (!method.isStatic() && !constructed.contains(jc)) {
+            HashSet hs = (HashSet)uponconstruction.get(jc);
+            if (hs == null) uponconstruction.put(jc, hs = new HashSet());
+            hs.add(method);
+            markMethodInSubclasses(jc, method, cpg);
+            dest.remove(method);
+            return;
+        }
 
         level += 2;
         for(int i=0; i<level; i++) System.out.print(" ");
-        ConstantPoolGen cpg = new ConstantPoolGen(method.getConstantPool());
-        System.out.println(jc.getClassName() + "." + getMethodSignature(method, cpg));
+        System.out.print(jc.getClassName() + "." + getMethodSignature(method, cpg));
         markMethodInSubclasses(jc, method, cpg);
-        if (method.getCode() == null) { level -= 2; return; }
+        if (method.getCode() == null) { System.out.println(); level -= 2; return; }
         byte[] code = method.getCode().getCode();
         InstructionList il = new InstructionList(code);
-        Instruction[] instructions = il.getInstructions();
+        InstructionHandle[] instructions = il.getInstructionHandles();
+        System.out.println(" [" + instructions.length + " instructions]");
         for(int i=0; i<instructions.length; i++){ 
-            Instruction instr = instructions[i];
+            Instruction instr = instructions[i].getInstruction();;
+            if (instr instanceof Select) {
+                InstructionHandle[] ih2 = ((Select)instr).getTargets();
+                InstructionHandle[] ih3 = new InstructionHandle[instructions.length + ih2.length];
+                System.arraycopy(instructions, 0, ih3, 0, instructions.length);
+                System.arraycopy(ih2, 0, ih3, instructions.length, ih2.length);
+                instructions = ih3;
+            }
             if (instr instanceof LoadClass) {
                 ObjectType ot = (ObjectType)((LoadClass)instr).getLoadClassType(cpg);
                 if (ot != null) loadMethod(ot.getClassName() + ".<clinit>");
             }
             if (instr instanceof CPInstruction) load(((CPInstruction)instr).getType(cpg));
-            if (instr instanceof TypedInstruction) {
-                try { load(((TypedInstruction)instr).getType(cpg)); } catch (Exception e) { /* DELIBERATE */ }
-            }
-            if (instr instanceof NEW) {
-                for(int j=0; j<level; j++) System.out.print(" ");
-                loadMethod(((NEW)instr).getLoadClassType(cpg).getClassName() + ".<init>");
-            }
+            if (instr instanceof TypedInstruction) load(((TypedInstruction)instr).getType(cpg));
+            if (instr instanceof NEW) loadMethod(((NEW)instr).getLoadClassType(cpg).getClassName() + ".<init>");
             if (instr instanceof org.apache.bcel.generic.FieldOrMethod)
                 load(((org.apache.bcel.generic.FieldOrMethod)instr).getClassType(cpg));
             if (instr instanceof org.apache.bcel.generic.FieldInstruction) {
@@ -286,7 +343,7 @@ public class BytecodePruner {
                 JavaClass jc2 = repo.loadClass(((ObjectType)((org.apache.bcel.generic.FieldInstruction)instr).
                                                 getLoadClassType(cpg)).getClassName());
                 Field[] fields = jc2.getFields();
-                for(int j=0; j<fields.length; j++) if (fields[j].getName().equals(fieldName)) visitJavaField(fields[j]);
+                for(int j=0; j<fields.length; j++) if (fields[j].getName().equals(fieldName)) visitJavaField(fields[j], jc2);
             }
             if (instr instanceof InvokeInstruction) {
                 InvokeInstruction ii = (InvokeInstruction)instr;
@@ -306,19 +363,19 @@ public class BytecodePruner {
                 if (!good) throw new Exception("couldn't find method " + getMethodSignature(ii, cpg) + " in " + c.getClassName());
             }
         }
-        level -= 2;
-
-        // FIXME: move this to the top
         Type[] argtypes = method.getArgumentTypes();
         for(int i=0; i<argtypes.length; i++) load(argtypes[i]);
         if (method.getExceptionTable() != null) {
             String[] exntypes = method.getExceptionTable().getExceptionNames();
             for(int i=0; i<exntypes.length; i++) load(exntypes[i]);
         }
+        level -= 2;
     }
 
-    public void visitJavaField(Field field) throws Exception {
-        if (!dest.contains(field)) dest.add(field);
+    public void visitJavaField(Field field, JavaClass clazz) throws Exception {
+        if (dest.contains(field)) return;
+        dest.add(field);
+        if (field.isStatic()) loadMethod(clazz.getClassName() + ".<clinit>");
     }
 
     public void visitJavaClass(JavaClass clazz) throws Exception {
@@ -326,6 +383,8 @@ public class BytecodePruner {
         dest.add(clazz);
 
         ConstantPoolGen cpg = new ConstantPoolGen(clazz.getConstantPool());
+        level += 2;
+        for(int i=0; i<level; i++) System.out.print(" ");
         System.out.println(clazz.getClassName() + ".class");
 
         JavaClass superclass = clazz.getSuperClass();
@@ -350,26 +409,23 @@ public class BytecodePruner {
 
         Field[] fields = clazz.getFields();
         for(int i=0; i<fields.length; i++) {
-            if (!fields[i].isStatic()) visitJavaField(fields[i]);
+            if (!fields[i].isStatic()) visitJavaField(fields[i], clazz);
             else {
                 Type t = fields[i].getType();
                 if (t instanceof ObjectType) load(t);
             }
         }
-
-        Method[] methods = getMethods(clazz);
-        for(int i=0; i<methods.length; i++) {
-            //if (methods[i].getName().equals("<clinit>")) visitJavaMethod(clazz, methods[i]);
-            if (methods[i].getName().equals("equals")) visitJavaMethod(clazz, methods[i]);
-            if (methods[i].getName().equals("hashCode")) visitJavaMethod(clazz, methods[i]);
-            if (methods[i].getName().equals("finalize")) visitJavaMethod(clazz, methods[i]);
-            if (methods[i].getName().equals("clone")) visitJavaMethod(clazz, methods[i]);
-            if (methods[i].getName().equals("toString")) visitJavaMethod(clazz, methods[i]);
-        }
+        level -= 2;
     }
 
     public void markMethodInSubclasses(JavaClass c, Method m, JavaClass subclass, ConstantPoolGen cpg) throws Exception {
         if (m.isStatic()) return;
+        if (m.getName().equals("<init>")) return;
+        if (m.getName().equals("equals")) return;
+        if (m.getName().equals("hashCode")) return;
+        if (m.getName().equals("clone")) return;
+        if (m.getName().equals("finalize")) return;
+        if (m.getName().equals("toString")) return;
         String sig = getMethodSignature(m, cpg);
         Method[] submethods = getMethods(subclass);
         for(int j=0; j<submethods.length; j++)
@@ -378,6 +434,7 @@ public class BytecodePruner {
     }
     public void markMethodInSubclasses(JavaClass c, Method m, ConstantPoolGen cpg) throws Exception {
         if (m.isStatic()) return;
+        if (m.getName().equals("<init>")) return;
         HashSet s = (HashSet)subclasses.get(c);
         if (s == null) return;
         Object[] subclasses = s.toArray();
@@ -390,12 +447,18 @@ public class BytecodePruner {
         
     public void remarkMethods(JavaClass c, ConstantPoolGen cpg) throws Exception {
         Method[] meths =getMethods(c);
-        for(int j=0; j<meths.length; j++) if (dest.contains(meths[j])) markMethodInSubclasses(c, meths[j], cpg);
+        for(int j=0; j<meths.length; j++)
+            if (dest.contains(meths[j]) ||
+                (uponconstruction.get(c) != null && ((HashSet)uponconstruction.get(c)).contains(meths[j])))
+                markMethodInSubclasses(c, meths[j], cpg);
     }
 
     public void remarkMethods(JavaClass c, JavaClass target, ConstantPoolGen cpg) throws Exception {
         Method[] meths = getMethods(c);
-        for(int j=0; j<meths.length; j++) if (dest.contains(meths[j])) markMethodInSubclasses(c, meths[j], target, cpg);
+        for(int j=0; j<meths.length; j++)
+            if (dest.contains(meths[j]) ||
+                (uponconstruction.get(c) != null && ((HashSet)uponconstruction.get(c)).contains(meths[j])))
+                markMethodInSubclasses(c, meths[j], target, cpg);
     }
 
     public static Hashtable methodsHashtable = new Hashtable();
diff --git a/upstream/gcc-3.3/patches/zzz-disable-reflection.patch b/upstream/gcc-3.3/patches/zzz-disable-reflection.patch
deleted file mode 100644 (file)
index 4c1fd67..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-diff -ru gcc/java/class.c gcc/java/class.c
---- gcc/java/class.c   Fri Feb 28 12:53:07 2003
-+++ gcc/java/class.c   Wed Feb 25 23:19:58 2004
-@@ -1254,25 +1254,32 @@
-   if (DECL_RTL_SET_P (mdecl))
-     code = build1 (ADDR_EXPR, nativecode_ptr_type_node, mdecl);
-   START_RECORD_CONSTRUCTOR (minit, method_type_node);
--  PUSH_FIELD_VALUE (minit, "name",
--                  build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
--                                  init_identifier_node
--                                  : DECL_NAME (mdecl)));
--  {
-+
-+  // FIXME: should walk up the tree looking to see if this method
-+  //        overrides one declared in an interface
-+  if (!flag_inhibit_reflection || !METHOD_STATIC(mdecl) || DECL_CLINIT_P(mdecl) ||
-+      (METHOD_STATIC(mdecl) && (strcmp(IDENTIFIER_POINTER(DECL_NAME(mdecl)),"main") == 0))) {
-+    PUSH_FIELD_VALUE (minit, "name",
-+                      build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
-+                                      init_identifier_node
-+                                      : DECL_NAME (mdecl)));
-     tree signature = build_java_signature (TREE_TYPE (mdecl));
-     PUSH_FIELD_VALUE (minit, "signature", 
--                    (build_utf8_ref 
--                     (unmangle_classname 
--                      (IDENTIFIER_POINTER(signature),
--                       IDENTIFIER_LENGTH(signature)))));
-+                      (build_utf8_ref 
-+                       (unmangle_classname 
-+                        (IDENTIFIER_POINTER(signature),
-+                         IDENTIFIER_LENGTH(signature)))));
-+  } else {
-+    PUSH_FIELD_VALUE (minit, "name", null_pointer_node);
-+    PUSH_FIELD_VALUE (minit, "signature", null_pointer_node);
-   }
-   PUSH_FIELD_VALUE (minit, "accflags", build_int_2 (accflags, 0));
-   PUSH_FIELD_VALUE (minit, "index", index);
-   PUSH_FIELD_VALUE (minit, "ncode", code);
--
-   {
-     /* Compute the `throws' information for the method.  */
-     tree table = null_pointer_node;
-+    if (!flag_inhibit_reflection)
-     if (DECL_FUNCTION_THROWS (mdecl) != NULL_TREE)
-       {
-       int length = 1 + list_length (DECL_FUNCTION_THROWS (mdecl));
-@@ -1454,6 +1461,7 @@
-   field = TYPE_FIELDS (type);
-   if (DECL_NAME (field) == NULL_TREE)
-     field = TREE_CHAIN (field);  /* Skip dummy field for inherited data. */
-+
-   for ( ;  field != NULL_TREE;  field = TREE_CHAIN (field))
-     {
-       if (! DECL_ARTIFICIAL (field))
-@@ -1462,8 +1470,11 @@
-         if (FIELD_STATIC (field))
-           {
-             tree initial = DECL_INITIAL (field);
-+  if (!flag_inhibit_reflection)
-+    {
-             static_field_count++;
-             static_fields = tree_cons (NULL_TREE, init, static_fields);
-+    }
-             /* If the initial value is a string constant,
-                prevent output_constant from trying to assemble the value. */
-             if (initial != NULL_TREE
-@@ -1473,6 +1484,7 @@
-             DECL_INITIAL (field) = initial;
-           }
-         else
-+  if (!flag_inhibit_reflection)
-           {
-             instance_field_count++;
-             instance_fields = tree_cons (NULL_TREE, init, instance_fields);
-diff -ru gcc/java/java-tree.h gcc/java/java-tree.h
---- gcc/java/java-tree.h       Mon Nov 18 10:13:35 2002
-+++ gcc/java/java-tree.h       Wed Feb 25 19:49:44 2004
-@@ -225,6 +225,9 @@
- /* Encoding used for source files.  */
- extern const char *current_encoding;
-+/** don't emit reflection information */
-+extern int flag_inhibit_reflection;
-+
- /* The Java .class file that provides main_class;  the main input file. */
- extern struct JCF *current_jcf;
-diff -ru gcc/java/lang.c gcc/java/lang.c
---- gcc/java/lang.c    Sun Jan  5 07:03:25 2003
-+++ gcc/java/lang.c    Wed Feb 25 19:49:49 2004
-@@ -171,6 +171,9 @@
- /* The encoding of the source file.  */
- const char *current_encoding = NULL;
-+/** don't emit reflection information */
-+int flag_inhibit_reflection = 0;
-+
- /* When nonzero, report the now deprecated empty statements.  */
- int flag_extraneous_semicolon;
-@@ -431,6 +434,13 @@
-     {
-       flag_inline_functions = 1;
-       flag_really_inline = 1;
-+      return 1;
-+    }
-+#undef ARG
-+#define ARG "-finhibit-reflection"
-+  if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
-+    {
-+      flag_inhibit_reflection = 1;
-       return 1;
-     }
- #undef ARG
-diff -ru libjava/boehm.cc libjava/boehm.cc
---- libjava/boehm.cc   Thu Jan  2 21:19:53 2003
-+++ libjava/boehm.cc   Wed Feb 25 23:43:44 2004
-@@ -17,6 +17,7 @@
- #include <java/lang/Class.h>
- #include <java/lang/reflect/Modifier.h>
-+#include <java/lang/VirtualMachineError.h>
- #include <java-interp.h>
- // More nastiness: the GC wants to define TRUE and FALSE.  We don't
-@@ -147,6 +148,7 @@
-         for (int i = 0; i < c->method_count; ++i)
-           {
-             p = (ptr_t) c->methods[i].name;
-+              if (p == NULL) continue;
-             MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c,
-                            cm1label);
-             p = (ptr_t) c->methods[i].signature;
-@@ -164,9 +166,11 @@
- #ifndef COMPACT_FIELDS
-         p = (ptr_t) field->name;
-+          if (p == NULL) continue;
-         MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c8alabel);
- #endif
-         p = (ptr_t) field->type;
-+          if (p == NULL) continue;
-         MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c8blabel);
-         // For the interpreter, we also need to mark the memory
-@@ -258,6 +262,7 @@
-       // Note: occasionally `klass' can be null.  For instance, this
-       // can happen if a GC occurs between the point where an object
-       // is allocated and where the vtbl slot is set.
-+      throw new java::lang::VirtualMachineError();
-       while (klass && klass != &java::lang::Object::class$)
-       {
-         jfieldID field = JvGetFirstInstanceField (klass);
-diff -ru libjava/gnu/gcj/convert/BytesToUnicode.java libjava/gnu/gcj/convert/BytesToUnicode.java
---- libjava/gnu/gcj/convert/BytesToUnicode.java        Mon Jul 30 13:24:17 2001
-+++ libjava/gnu/gcj/convert/BytesToUnicode.java        Wed Feb 25 22:53:54 2004
-@@ -65,7 +65,7 @@
-       }
-     catch (Throwable ex)
-       {
--      return new Input_8859_1();
-+          throw new UnsatisfiedLinkError();
-       }
-   }
-diff -ru libjava/gnu/gcj/convert/UnicodeToBytes.java libjava/gnu/gcj/convert/UnicodeToBytes.java
---- libjava/gnu/gcj/convert/UnicodeToBytes.java        Fri Aug 17 20:56:01 2001
-+++ libjava/gnu/gcj/convert/UnicodeToBytes.java        Wed Feb 25 22:53:48 2004
-@@ -63,7 +63,8 @@
-       }
-     catch (Throwable ex)
-       {
--      return new Output_8859_1();
-+          throw new UnsatisfiedLinkError();
-+          //return new Output_8859_1();
-       }
-   }
-diff -ru libjava/java/lang/Class.h libjava/java/lang/Class.h
---- libjava/java/lang/Class.h  Sun Jan 19 22:49:28 2003
-+++ libjava/java/lang/Class.h  Wed Feb 25 21:34:30 2004
-@@ -80,7 +80,6 @@
-   // NULL-terminated list of exception class names; can be NULL if
-   // there are none such.
-   _Jv_Utf8Const **throws;
--
-   _Jv_Method *getNextMethod ()
-   { return this + 1; }
- };
-diff -ru libjava/java/lang/natClass.cc libjava/java/lang/natClass.cc
---- libjava/java/lang/natClass.cc      Thu May  1 14:52:35 2003
-+++ libjava/java/lang/natClass.cc      Wed Feb 25 22:59:34 2004
-@@ -808,10 +808,12 @@
-   // Steps 8, 9, 10, 11.
-   try
-     {
-+      /*
-       _Jv_Method *meth = _Jv_GetMethodLocal (this, clinit_name,
-                                            void_signature);
-       if (meth)
-       ((void (*) (void)) meth->ncode) ();
-+      */
-     }
-   catch (java::lang::Throwable *except)
-     {
-@@ -1326,13 +1328,13 @@
-         if (meth)
-           break;
-       }
--
-+      /*
-       if (meth && (meth->name->data[0] == '<'))
-       {
-         // leave a placeholder in the itable for hidden init methods.
-           itable[pos] = NULL; 
-       }
--      else if (meth)
-+        else*/ if (meth)
-         {
-         if (Modifier::isStatic(meth->accflags))
-           throw new java::lang::IncompatibleClassChangeError
-diff -ru libjava/libgcj.spec.in libjava/libgcj.spec.in
---- libjava/libgcj.spec.in     Wed Feb 12 18:09:27 2003
-+++ libjava/libgcj.spec.in     Wed Feb 25 19:51:22 2004
-@@ -4,6 +4,6 @@
- # to link with libgcj.
- #
- %rename lib liborig
--*lib: -lgcj -lm @LIBICONV@ @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) %(liborig)
-+*lib: -lm @LIBICONV@ @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) %(liborig)
- *jc1: @HASH_SYNC_SPEC@ @DIVIDESPEC@ @CHECKREFSPEC@ @JC1GCSPEC@ @EXCEPTIONSPEC@ @BACKTRACESPEC@ @IEEESPEC@ -fkeep-inline-functions
-diff -ru libjava/prims.cc libjava/prims.cc
---- libjava/prims.cc   Fri Apr 25 09:02:21 2003
-+++ libjava/prims.cc   Wed Feb 25 23:16:52 2004
-@@ -165,6 +165,7 @@
- {
-   int len;
-   _Jv_ushort *aptr, *bptr;
-+  if (a == NULL || b == NULL) return false;
-   if (a == b)
-     return true;
-   if (a->hash != b->hash)
-@@ -188,6 +189,7 @@
- jboolean
- _Jv_equal (Utf8Const* a, jstring str, jint hash)
- {
-+  if (a == NULL) return false;
-   if (a->hash != (_Jv_ushort) hash)
-     return false;
-   jint len = str->length();
-@@ -210,6 +212,7 @@
- jboolean
- _Jv_equaln (Utf8Const *a, jstring str, jint n)
- {
-+  if (a == NULL) return false;
-   jint len = str->length();
-   jint i = 0;
-   jchar *sptr = _Jv_GetStringChars (str);
diff --git a/upstream/gcc-3.3/patches/zzz-inhibit.reflection.patch b/upstream/gcc-3.3/patches/zzz-inhibit.reflection.patch
new file mode 100644 (file)
index 0000000..c2a72c7
--- /dev/null
@@ -0,0 +1,737 @@
+diff -rBubboehm-gc/configureboehm-gc/configure
+---boehm-gc/configure  Tue May 13 17:18:14 2003
++++boehm-gc/configure  Mon Mar  1 01:03:55 2004
+@@ -1181,9 +1181,9 @@
+   if test "$ac_test_CFLAGS" = set; then
+     CFLAGS="$ac_save_CFLAGS"
+   elif test $ac_cv_prog_cc_g = yes; then
+-    CFLAGS="-g -O2"
++    CFLAGS="-g -Os -ffunction-sections -fdata-sections"
+   else
+-    CFLAGS="-O2"
++    CFLAGS="-Os -ffunction-sections -fdata-sections"
+   fi
+ else
+   GCC=
+@@ -1275,9 +1275,9 @@
+   if test "$ac_test_CXXFLAGS" = set; then
+     CXXFLAGS="$ac_save_CXXFLAGS"
+   elif test $ac_cv_prog_cxx_g = yes; then
+-    CXXFLAGS="-g -O2"
++    CXXFLAGS="-g -Os -ffunction-sections -fdata-sections"
+   else
+-    CXXFLAGS="-O2"
++    CXXFLAGS="-Os -ffunction-sections -fdata-sections"
+   fi
+ else
+   GXX=
+diff -rBubgcc/dwarf2out.cgcc/dwarf2out.c
+---gcc/dwarf2out.c     Mon May  5 09:59:20 2003
++++gcc/dwarf2out.c     Sat Feb 28 02:37:20 2004
+@@ -1040,6 +1040,8 @@
+   else if (!flag_asynchronous_unwind_tables && cfa.reg != STACK_POINTER_REGNUM)
+     return;
++  if (frame_pointer_needed) return;
++
+   if (GET_CODE (insn) == BARRIER)
+     {
+       /* When we see a BARRIER, we know to reset args_size to 0.  Usually
+diff -rBubgcc/java/class.cgcc/java/class.c
+---gcc/java/class.c    Fri Feb 28 12:53:07 2003
++++gcc/java/class.c    Mon Mar  1 00:20:15 2004
+@@ -971,7 +971,7 @@
+      tree type;
+ {
+   int is_compiled = is_compiled_class (type);
+-  if (is_compiled)
++  if (is_compiled || flag_inhibit_reflection)
+     {
+       tree ref, decl_name, decl;
+       if (TREE_CODE (type) == POINTER_TYPE)
+@@ -1199,13 +1199,17 @@
+   int resolved = is_compiled_class (type);
+   START_RECORD_CONSTRUCTOR (finit, field_type_node);
++  if (!flag_inhibit_reflection) {
+   PUSH_FIELD_VALUE (finit, "name", build_utf8_ref (DECL_NAME (fdecl)));
++  } else {
++    PUSH_FIELD_VALUE (finit, "name", null_pointer_node);
++  }
+   if (resolved)
+     type = build_class_ref (type);
+   else
+     {
++      if (!flag_inhibit_reflection) {
+       tree signature = build_java_signature (type);
+-
+       type = build_utf8_ref (unmangle_classname 
+                            (IDENTIFIER_POINTER (signature),
+                             IDENTIFIER_LENGTH (signature)));
+@@ -1209,6 +1213,9 @@
+       type = build_utf8_ref (unmangle_classname 
+                            (IDENTIFIER_POINTER (signature),
+                             IDENTIFIER_LENGTH (signature)));
++      } else {
++        type = null_pointer_node;
++      }
+     }
+   PUSH_FIELD_VALUE (finit, "type", type);
+@@ -1244,6 +1251,7 @@
+   tree code;
+ #define ACC_TRANSLATED          0x4000
+   int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
++  int emitNames = 0;
+   if (!flag_indirect_dispatch && DECL_VINDEX (mdecl) != NULL_TREE)
+     index = DECL_VINDEX (mdecl);
+@@ -1254,6 +1262,12 @@
+   if (DECL_RTL_SET_P (mdecl))
+     code = build1 (ADDR_EXPR, nativecode_ptr_type_node, mdecl);
+   START_RECORD_CONSTRUCTOR (minit, method_type_node);
++
++  emitNames = !flag_inhibit_reflection;
++  if (!METHOD_STATIC(mdecl)) emitNames = 1;
++  if (DECL_CLINIT_P(mdecl)) emitNames = 1;
++  if ((METHOD_STATIC(mdecl) && (strcmp(IDENTIFIER_POINTER(DECL_NAME(mdecl)),"main") == 0))) emitNames = 1;
++  if (emitNames) {
+   PUSH_FIELD_VALUE (minit, "name",
+                   build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
+                                   init_identifier_node
+@@ -1266,6 +1280,10 @@
+                       (IDENTIFIER_POINTER(signature),
+                        IDENTIFIER_LENGTH(signature)))));
+   }
++  } else {
++    PUSH_FIELD_VALUE (minit, "name", null_pointer_node);
++    PUSH_FIELD_VALUE (minit, "signature", null_pointer_node);
++  }
+   PUSH_FIELD_VALUE (minit, "accflags", build_int_2 (accflags, 0));
+   PUSH_FIELD_VALUE (minit, "index", index);
+   PUSH_FIELD_VALUE (minit, "ncode", code);
+@@ -1273,6 +1291,7 @@
+   {
+     /* Compute the `throws' information for the method.  */
+     tree table = null_pointer_node;
++  if (!flag_inhibit_reflection)
+     if (DECL_FUNCTION_THROWS (mdecl) != NULL_TREE)
+       {
+       int length = 1 + list_length (DECL_FUNCTION_THROWS (mdecl));
+@@ -1473,6 +1493,7 @@
+             DECL_INITIAL (field) = initial;
+           }
+         else
++  if (!flag_inhibit_reflection)
+           {
+             instance_field_count++;
+             instance_fields = tree_cons (NULL_TREE, init, instance_fields);
+@@ -1480,6 +1501,9 @@
+       }
+     }
+   field_count = static_field_count + instance_field_count;
++  
++  // we have to leave this here; part of the class initialization is the process
++  // of replacing utf8const's with String objects
+   if (field_count > 0)
+     {
+       static_fields = nreverse (static_fields);
+@@ -1550,7 +1574,7 @@
+   super = CLASSTYPE_SUPER (type);
+   if (super == NULL_TREE)
+     super = null_pointer_node;
+-  else if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl))))
++  else if (flag_inhibit_reflection || (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))))
+     super = build_class_ref (super);
+   else
+     {
+@@ -1576,7 +1600,7 @@
+         tree child = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i);
+         tree iclass = BINFO_TYPE (child);
+         tree index;
+-        if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass)))))
++        if (flag_inhibit_reflection || (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass))))))
+           index = build_class_ref (iclass);
+         else
+           {
+@@ -2225,6 +2249,7 @@
+   index = 0;
+   method_list = otable_methods;
+   list = NULL_TREE;  
++  if (!flag_inhibit_reflection)
+   while (method_list != NULL_TREE)
+     {
+       method = TREE_VALUE (method_list);
+diff -rBubgcc/java/constants.cgcc/java/constants.c
+---gcc/java/constants.c        Mon Nov 18 07:46:32 2002
++++gcc/java/constants.c        Mon Mar  1 00:20:32 2004
+@@ -430,9 +430,13 @@
+   int i;
+   for (i = outgoing_cpool->count;  --i > 0; )
+     {
++      if (!flag_inhibit_reflection) {
+       tags_list
+       = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
+                    tags_list);
++      } else {
++        tags_list = null_pointer_node;
++      }
+       data_list
+       = tree_cons (NULL_TREE, build_utf8_ref ((tree)outgoing_cpool->data[i]),
+                    data_list);
+@@ -446,7 +450,9 @@
+       index_type = build_index_type (max_index);
+       /* Add dummy 0'th element of constant pool. */
++      if (!flag_inhibit_reflection) {
+       tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list);
++      }
+       data_list = tree_cons (NULL_TREE, null_pointer_node, data_list);
+   
+       data_decl = TREE_OPERAND (build_constant_data_ref (), 0);
+@@ -458,6 +464,7 @@
+       rest_of_decl_compilation (data_decl, (char *) 0, 1, 0);
+       data_value = build_address_of (data_decl);
++      if (!flag_inhibit_reflection) {
+       tags_type = build_array_type (unsigned_byte_type_node, index_type);
+       tags_decl = build_decl (VAR_DECL, mangled_classname ("_CT_", 
+                                                          current_class),
+@@ -467,6 +474,9 @@
+                                       NULL_TREE, tags_list);
+       rest_of_decl_compilation (tags_decl, (char*) 0, 1, 0);
+       tags_value = build_address_of (tags_decl);
++      } else {
++        tags_value = null_pointer_node;
++      }
+     }
+   else
+     {
+diff -rBubgcc/java/java-tree.hgcc/java/java-tree.h
+---gcc/java/java-tree.h        Mon Nov 18 10:13:35 2002
++++gcc/java/java-tree.h        Thu Feb 26 15:01:38 2004
+@@ -225,6 +225,9 @@
+ /* Encoding used for source files.  */
+ extern const char *current_encoding;
++/** don't emit reflection information */
++extern int flag_inhibit_reflection;
++
+ /* The Java .class file that provides main_class;  the main input file. */
+ extern struct JCF *current_jcf;
+diff -rBubgcc/java/lang.cgcc/java/lang.c
+---gcc/java/lang.c     Sun Jan  5 07:03:25 2003
++++gcc/java/lang.c     Thu Feb 26 15:01:38 2004
+@@ -171,6 +171,9 @@
+ /* The encoding of the source file.  */
+ const char *current_encoding = NULL;
++/** don't emit reflection information */
++int flag_inhibit_reflection = 0;
++
+ /* When nonzero, report the now deprecated empty statements.  */
+ int flag_extraneous_semicolon;
+@@ -431,6 +434,13 @@
+     {
+       flag_inline_functions = 1;
+       flag_really_inline = 1;
++      return 1;
++    }
++#undef ARG
++#define ARG "-finhibit-reflection"
++  if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
++    {
++      flag_inhibit_reflection = 1;
+       return 1;
+     }
+ #undef ARG
+diff -rBublibjava/Makefile.inlibjava/Makefile.in
+---libjava/Makefile.in Mon Mar  1 01:45:58 2004
++++libjava/Makefile.in Sun Feb 29 22:09:27 2004
+@@ -174,10 +174,10 @@
+ WARNINGS = -W -Wall
+ AM_CXXFLAGS = -fno-rtti -fnon-call-exceptions \
+-      -fdollars-in-identifiers \
++      -fdollars-in-identifiers -ffunction-sections -fdata-sections \
+       -Wswitch-enum \
+       @LIBGCJ_CXXFLAGS@ @X_CFLAGS@ $(WARNINGS) -D_GNU_SOURCE \
+-      -DPREFIX="\"$(prefix)\""
++      -DPREFIX="\"$(prefix)\"" -Os
+ @USING_GCC_TRUE@AM_CFLAGS = @USING_GCC_TRUE@@LIBGCJ_CFLAGS@ $(WARNINGS)
+ @USING_GCC_FALSE@AM_CFLAGS = @USING_GCC_FALSE@@LIBGCJ_CFLAGS@
+diff -rBublibjava/boehm.cclibjava/boehm.cc
+---libjava/boehm.cc    Thu Jan  2 21:19:53 2003
++++libjava/boehm.cc    Mon Mar  1 00:21:04 2004
+@@ -17,6 +17,7 @@
+ #include <java/lang/Class.h>
+ #include <java/lang/reflect/Modifier.h>
++#include <java/lang/VirtualMachineError.h>
+ #include <java-interp.h>
+ // More nastiness: the GC wants to define TRUE and FALSE.  We don't
+@@ -147,6 +149,7 @@
+         for (int i = 0; i < c->method_count; ++i)
+           {
+             p = (ptr_t) c->methods[i].name;
++              if (p == NULL) continue;
+             MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c,
+                            cm1label);
+             p = (ptr_t) c->methods[i].signature;
+@@ -164,9 +167,11 @@
+ #ifndef COMPACT_FIELDS
+         p = (ptr_t) field->name;
++          if (p == NULL) continue;
+         MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c8alabel);
+ #endif
+         p = (ptr_t) field->type;
++          if (p == NULL) continue;
+         MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c8blabel);
+         // For the interpreter, we also need to mark the memory
+@@ -258,6 +263,7 @@
+       // Note: occasionally `klass' can be null.  For instance, this
+       // can happen if a GC occurs between the point where an object
+       // is allocated and where the vtbl slot is set.
++      throw new java::lang::VirtualMachineError();
+       while (klass && klass != &java::lang::Object::class$)
+       {
+         jfieldID field = JvGetFirstInstanceField (klass);
+diff -rBublibjava/configurelibjava/configure
+---libjava/configure   Mon Mar  1 01:45:59 2004
++++libjava/configure   Sun Feb 29 22:13:11 2004
+@@ -1180,13 +1180,13 @@
+   CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+   if test "$GCC" = yes; then
+-    CFLAGS="-g -O2"
++    CFLAGS="-g -Os"
+   else
+     CFLAGS="-g"
+   fi
+ else
+   if test "$GCC" = yes; then
+-    CFLAGS="-O2"
++    CFLAGS="-Os"
+   else
+     CFLAGS=
+   fi
+@@ -1287,9 +1287,9 @@
+   if test "$ac_test_CXXFLAGS" = set; then
+     CXXFLAGS="$ac_save_CXXFLAGS"
+   elif test $ac_cv_prog_cxx_g = yes; then
+-    CXXFLAGS="-g -O2"
++    CXXFLAGS="-g -Os"
+   else
+-    CXXFLAGS="-O2"
++    CXXFLAGS="-Os"
+   fi
+ else
+   GXX=
+@@ -1683,6 +1683,9 @@
++cat >> confdefs.h <<\EOF
++#undef USE_LTDL
++EOF
+ # Only use libltdl for native builds.
+@@ -1697,9 +1700,9 @@
+    
+    DIRLTDL=libltdl
+-   cat >> confdefs.h <<\EOF
+-#define USE_LTDL 1
+-EOF
++#   cat >> confdefs.h <<\EOF
++##define USE_LTDL 1
++#EOF
+    # Sigh.  Libtool's macro doesn't do the right thing.
+    INCLTDL="-I\$(top_srcdir)/libltdl $INCLTDL"
+@@ -5644,7 +5647,7 @@
+ fi
+ fi
+-  test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
++  test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -Os"
+   
+@@ -5798,7 +5801,7 @@
+ echo $ac_n "checking for g++ -ffloat-store bug""... $ac_c" 1>&6
+ echo "configure:5796: checking for g++ -ffloat-store bug" >&5
+ save_CFLAGS="$CFLAGS"
+-CFLAGS="-x c++ -O2 -ffloat-store"
++CFLAGS="-x c++ -Os -ffloat-store"
+ cat > conftest.$ac_ext <<EOF
+ #line 5800 "configure"
+ #include "confdefs.h"
+diff -rBublibjava/configure.inlibjava/configure.in
+---libjava/configure.in        Mon Mar  1 01:45:59 2004
++++libjava/configure.in        Mon Mar  1 00:28:09 2004
+@@ -825,7 +825,7 @@
+ dnl Work around a g++ bug.  Reported to gcc-bugs@gcc.gnu.org on Jan 22, 2000.
+ AC_MSG_CHECKING([for g++ -ffloat-store bug])
+ save_CFLAGS="$CFLAGS"
+-CFLAGS="-x c++ -O2 -ffloat-store"
++CFLAGS="-x c++ -Os -ffloat-store"
+ AC_TRY_COMPILE([#include <math.h>], , 
+   [AC_MSG_RESULT(no)],
+   [AC_DEFINE(__NO_MATH_INLINES)
+diff -rBublibjava/gnu/gcj/convert/BytesToUnicode.javalibjava/gnu/gcj/convert/BytesToUnicode.java
+---libjava/gnu/gcj/convert/BytesToUnicode.java Mon Jul 30 13:24:17 2001
++++libjava/gnu/gcj/convert/BytesToUnicode.java Fri Feb 27 04:17:13 2004
+@@ -65,7 +65,7 @@
+       }
+     catch (Throwable ex)
+       {
+-      return new Input_8859_1();
++          throw new UnsatisfiedLinkError();
+       }
+   }
+@@ -100,6 +100,7 @@
+       } 
+     catch (Throwable ex) 
+       { 
++          /*
+       try
+         {
+           // We pass the original name to iconv and let it handle
+@@ -108,9 +109,10 @@
+         }
+       catch (Throwable _)
+         {
++          */
+           throw new java.io.UnsupportedEncodingException(encoding
+                                                          + " (" + ex + ')');
+-        }
++            //}
+       }
+   }
+diff -rBublibjava/gnu/gcj/convert/IOConverter.javalibjava/gnu/gcj/convert/IOConverter.java
+---libjava/gnu/gcj/convert/IOConverter.java    Sun Sep 16 19:28:53 2001
++++libjava/gnu/gcj/convert/IOConverter.java    Sun Feb 29 01:53:14 2004
+@@ -20,7 +20,7 @@
+   // True if we have to do byte-order conversions on iconv()
+   // arguments.
+-  static protected boolean iconv_byte_swap;
++  static protected boolean iconv_byte_swap = false;
+   static
+   {
+@@ -64,7 +64,7 @@
+     hash.put ("cseucpkdfmtjapanese", "EUCJIS");
+     hash.put ("euc-jp", "EUCJIS");
+-    iconv_byte_swap = iconv_init ();
++    //iconv_byte_swap = iconv_init ();
+   }
+   private static native boolean iconv_init ();
+diff -rBublibjava/gnu/gcj/convert/UnicodeToBytes.javalibjava/gnu/gcj/convert/UnicodeToBytes.java
+---libjava/gnu/gcj/convert/UnicodeToBytes.java Fri Aug 17 20:56:01 2001
++++libjava/gnu/gcj/convert/UnicodeToBytes.java Fri Feb 27 04:17:02 2004
+@@ -63,7 +63,8 @@
+       }
+     catch (Throwable ex)
+       {
+-      return new Output_8859_1();
++          throw new UnsatisfiedLinkError();
++          //return new Output_8859_1();
+       }
+   }
+@@ -97,6 +98,7 @@
+       } 
+     catch (Throwable ex) 
+       { 
++          /*
+       try
+         {
+           // We pass the original name to iconv and let it handle
+@@ -105,10 +107,11 @@
+         }
+       catch (Throwable _)
+         {
++          */
+           // Put the original exception in the throwable.
+           throw new java.io.UnsupportedEncodingException(encoding + " ("
+                                                          + ex + ')');
+-        }
++            //}
+       }
+   }
+diff -rBublibjava/gnu/gcj/runtime/FirstThread.javalibjava/gnu/gcj/runtime/FirstThread.java
+---libjava/gnu/gcj/runtime/FirstThread.java    Wed Oct 10 15:25:43 2001
++++libjava/gnu/gcj/runtime/FirstThread.java    Fri Feb 27 05:05:29 2004
+@@ -90,8 +90,10 @@
+   // classes are linked in.  Otherwise bootstrapping fails.  These
+   // classes are only referred to via Class.forName(), so we add an
+   // explicit mention of them here.
++    /*
+   static final Class Kcert = java.security.cert.Certificate.class;
+   static final Class Kfile = gnu.gcj.protocol.file.Handler.class;
+   static final Class Khttp = gnu.gcj.protocol.http.Handler.class;
+   static final Class Kjar  = gnu.gcj.protocol.jar.Handler.class;
++    */
+ }
+diff -rBublibjava/gnu/gcj/runtime/VMClassLoader.javalibjava/gnu/gcj/runtime/VMClassLoader.java
+---libjava/gnu/gcj/runtime/VMClassLoader.java  Sun Dec  8 16:03:59 2002
++++libjava/gnu/gcj/runtime/VMClassLoader.java  Fri Feb 27 04:20:56 2004
+@@ -14,13 +14,15 @@
+ import java.util.StringTokenizer;
+ import java.net.URL;
+-public final class VMClassLoader extends java.net.URLClassLoader
++public final class VMClassLoader extends java.lang.ClassLoader //java.net.URLClassLoader
+ {
+   private VMClassLoader ()
+   {   
++      /*
+     super (init());
++      */
+   }
+-
++    /*
+   private static URL[] init() 
+   {
+     StringTokenizer st
+@@ -40,7 +42,7 @@
+         } 
+       catch (java.net.MalformedURLException x)
+         {
+-          /* Ignore this path element */
++          // Ignore this path element
+         }
+       }
+     // Add core:/ to the end of the java.class.path so any resources
+@@ -58,7 +60,7 @@
+     p.copyInto (urls);
+     return urls;
+   }
+-
++*/
+   /** This is overridden to search the internal hash table, which 
+    * will only search existing linked-in classes.   This will make
+    * the default implementation of loadClass (in ClassLoader) work right.
+diff -rBublibjava/gnu/gcj/runtime/natVMClassLoader.cclibjava/gnu/gcj/runtime/natVMClassLoader.cc
+---libjava/gnu/gcj/runtime/natVMClassLoader.cc Tue Dec 10 19:15:14 2002
++++libjava/gnu/gcj/runtime/natVMClassLoader.cc Fri Feb 27 04:22:00 2004
+@@ -60,8 +60,9 @@
+     }
+   // Now try loading using the interpreter.
++  /*
+   if (! klass)
+     klass = java::net::URLClassLoader::findClass (name);
+-
++  */
+   return klass;
+ }
+diff -rBublibjava/java/lang/Class.javalibjava/java/lang/Class.java
+---libjava/java/lang/Class.java        Tue Sep  3 14:33:46 2002
++++libjava/java/lang/Class.java        Sat Feb 28 22:48:09 2004
+@@ -241,6 +241,7 @@
+    */
+   public ProtectionDomain getProtectionDomain()
+   {
++      /*
+     SecurityManager sm = System.getSecurityManager();
+     if (sm != null)
+       sm.checkPermission(ClassLoader.protectionDomainPermission);
+@@ -248,9 +249,12 @@
+     ProtectionDomain protectionDomain = getProtectionDomain0();
+     if (protectionDomain == null)
++      */
+       return ClassLoader.unknownProtectionDomain;
++      /*
+     else
+       return protectionDomain;
++      */
+   }
+   public String toString ()
+diff -rBublibjava/java/lang/ClassLoader.javalibjava/java/lang/ClassLoader.java
+---libjava/java/lang/ClassLoader.java  Fri Jan 24 11:38:24 2003
++++libjava/java/lang/ClassLoader.java  Sat Feb 28 21:07:31 2004
+@@ -345,8 +345,8 @@
+   // FIXME: should there be a special protection domain used for native code?
+   
+   // The permission required to check what a classes protection domain is.
+-  static final Permission protectionDomainPermission
+-    = new RuntimePermission("getProtectionDomain");
++    //static final Permission protectionDomainPermission;
++    //= new RuntimePermission("getProtectionDomain");
+   // The protection domain returned if we cannot determine it. 
+   static ProtectionDomain unknownProtectionDomain;
+   // Protection domain to use when a class is defined without one specified.
+@@ -355,12 +355,14 @@
+   static
+   {
+     Permissions permissions = new Permissions();
+-    permissions.add(new AllPermission());
+-    unknownProtectionDomain = new ProtectionDomain(null, permissions);  
++    //permissions.add(new AllPermission());
++    //unknownProtectionDomain = new ProtectionDomain(null, permissions);  
++    /*
+     CodeSource cs = new CodeSource(null, null);
+     defaultProtectionDomain =
+       new ProtectionDomain(cs, Policy.getPolicy().getPermissions(cs));
++    */
+   }
+   /** 
+diff -rBublibjava/java/lang/SecurityManager.javalibjava/java/lang/SecurityManager.java
+---libjava/java/lang/SecurityManager.java      Sun Dec  1 08:16:19 2002
++++libjava/java/lang/SecurityManager.java      Fri Feb 27 02:08:27 2004
+@@ -297,7 +297,8 @@
+   public Object getSecurityContext()
+   {
+     // XXX Should be: return AccessController.getContext();
+-    return new SecurityContext(getClassContext());
++      //return new SecurityContext(getClassContext());
++      return null;
+   }
+   /**
+diff -rBublibjava/java/lang/natClass.cclibjava/java/lang/natClass.cc
+---libjava/java/lang/natClass.cc       Thu May  1 14:52:35 2003
++++libjava/java/lang/natClass.cc       Mon Mar  1 01:00:12 2004
+@@ -72,8 +72,10 @@
+   _Jv_Utf8Const *name = _Jv_makeUtf8Const (buffer, length);
++  /*
+   if (! _Jv_VerifyClassName (name))
+     throw new java::lang::ClassNotFoundException (className);
++  */
+   jclass klass = (buffer[0] == '[' 
+                 ? _Jv_FindClassFromSignature (name->data, loader)
+@@ -1518,7 +1520,7 @@
+     return;
+   
+   klass->otable->state = 1;
+-
++  return;
+   int index = 0;
+   _Jv_MethodSymbol sym = klass->otable_syms[0];
+diff -rBublibjava/java/lang/natClassLoader.cclibjava/java/lang/natClassLoader.cc
+---libjava/java/lang/natClassLoader.cc Thu Dec 19 11:32:17 2002
++++libjava/java/lang/natClassLoader.cc Sun Feb 29 23:55:48 2004
+@@ -195,6 +195,7 @@
+   _Jv_Constants *pool = &klass->constants;
+   for (int index = 1; index < pool->size; ++index)
+     {
++      /*
+       if (pool->tags[index] == JV_CONSTANT_Class)
+       {
+         _Jv_Utf8Const *name = pool->data[index].utf8;
+@@ -217,12 +218,13 @@
+       }
+       else if (pool->tags[index] == JV_CONSTANT_String)
+       {
++      */
+         jstring str;
+         str = _Jv_NewStringUtf8Const (pool->data[index].utf8);
+         pool->data[index].o = str;
+-        pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
+-      }
++        //pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
++          //}
+     }
+ #ifdef INTERPRETER
+@@ -253,10 +255,10 @@
+   if (klass->vtable == NULL)
+     _Jv_MakeVTable(klass);
+-
++  /*
+   if (klass->otable != NULL && klass->otable->state == 0)
+     _Jv_LinkOffsetTable(klass);
+-
++  */
+   klass->notifyAll ();
+   _Jv_PushClass (klass);
+diff -rBublibjava/java/security/Security.javalibjava/java/security/Security.java
+---libjava/java/security/Security.java Tue Dec 31 14:49:37 2002
++++libjava/java/security/Security.java Sat Feb 28 21:33:32 2004
+@@ -60,9 +60,11 @@
+   static
+   {
++      /*
+     String base = System.getProperty("gnu.classpath.home.url");
+     loadProviders(base, System.getProperty("gnu.classpath.vm.shortname"));
+     loadProviders(base, "classpath");
++      */
+   }
+   // This class can't be instantiated.
+diff -rBublibjava/libgcj.spec.inlibjava/libgcj.spec.in
+---libjava/libgcj.spec.in      Wed Feb 12 18:09:27 2003
++++libjava/libgcj.spec.in      Sun Feb 29 17:15:19 2004
+@@ -4,6 +4,7 @@
+ # to link with libgcj.
+ #
+ %rename lib liborig
+-*lib: -lgcj -lm @LIBICONV@ @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) %(liborig)
++*lib: -lm @LIBICONV@ @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) %(liborig)
++
++*jc1: @HASH_SYNC_SPEC@ @DIVIDESPEC@ @CHECKREFSPEC@ @JC1GCSPEC@ @EXCEPTIONSPEC@ @BACKTRACESPEC@ @IEEESPEC@ -fkeep-inline-functions -fno-omit-frame-pointer -Os -ffunction-sections -fdata-sections
+-*jc1: @HASH_SYNC_SPEC@ @DIVIDESPEC@ @CHECKREFSPEC@ @JC1GCSPEC@ @EXCEPTIONSPEC@ @BACKTRACESPEC@ @IEEESPEC@ -fkeep-inline-functions
+diff -rBublibjava/prims.cclibjava/prims.cc
+---libjava/prims.cc    Fri Apr 25 09:02:21 2003
++++libjava/prims.cc    Sat Feb 28 20:32:25 2004
+@@ -165,6 +165,7 @@
+ {
+   int len;
+   _Jv_ushort *aptr, *bptr;
++  if (a == NULL || b == NULL) return false;
+   if (a == b)
+     return true;
+   if (a->hash != b->hash)
+@@ -188,6 +189,7 @@
+ jboolean
+ _Jv_equal (Utf8Const* a, jstring str, jint hash)
+ {
++  if (a == NULL) return false;
+   if (a->hash != (_Jv_ushort) hash)
+     return false;
+   jint len = str->length();
+@@ -210,6 +212,7 @@
+ jboolean
+ _Jv_equaln (Utf8Const *a, jstring str, jint n)
+ {
++  if (a == NULL) return false;
+   jint len = str->length();
+   jint i = 0;
+   jchar *sptr = _Jv_GetStringChars (str);
+@@ -936,7 +939,7 @@
+   _Jv_platform_initialize ();
+-  _Jv_JNI_Init ();
++  //  _Jv_JNI_Init ();
+   _Jv_GCInitializeFinalizers (&::gnu::gcj::runtime::FinalizerThread::finalizerReady);