From: adam Date: Wed, 18 Feb 2004 11:28:34 +0000 (+0000) Subject: pruner mostly working X-Git-Tag: RC3~30 X-Git-Url: http://git.megacz.com/?p=org.ibex.core.git;a=commitdiff_plain;h=769cf53f52755d6b8c976edb561e3c21700447aa pruner mostly working darcs-hash:20040218112834-5007d-b475b3d44a504e35f671259c997aecbc047919c7.gz --- diff --git a/Makefile b/Makefile index cb554f0..671af44 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,8 @@ # The Ibex Makefile # +# auto directory creation with %/%: %? + target_Darwin := powerpc-apple-darwin target_Win32 := i686-pc-mingw32 target_Solaris := sparc-sun-solaris2.7 @@ -178,7 +180,7 @@ build/$(platform)/org/ibex/plat/AWT.java.o: ; touch .empty.c; mkdir -p $(@D); build/$(platform)/%.java.o: build/class/%.class @echo -e "\n\033[1mcompiling .java -> .o: $<\033[0m" mkdir -p `dirname $@` - $(gcj) -fCLASSPATH=build/class -c $< -o $@ + $(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) @@ -203,6 +205,10 @@ 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 build/$(platform)/builtin.o build/$(platform)/org/ibex/plat/$(platform).cc.o @echo -e "\n\033[1mlinking .o -> $(target_bin)\033[0m" + find upstream/gcc-3.3/build-i686-pc-linux-gnu/i686-pc-linux-gnu/libjava/ \ + -name nat\*.o -or \( -name \*.o -not -name '*[A-Z]*' \) -exec nm {} \; |\ + grep _ZN | c++filt --format java | grep " U " | sed 's_\.class\$$_.class_' | sed 's_ * U __' | sed 's_(.*__' \ + > .natcalls make $(java_sources) 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 @@ -215,43 +221,79 @@ build/$(platform)/$(target_bin): upstream/jpeg-6b/build-$(target)/libjpeg.a buil 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 -# rm -rf out/java/awt -# rm -f out/java/lang/*.* -# rm -f out/java/lang/reflect/* -# mkdir -p out/java/lang/ref -# mkdir -p out/java/lang/reflect -# cp upstream/gcc-3.3/src/libjava/java/lang/*.java out/java/lang/ -# cp upstream/gcc-3.3/src/libjava/java/lang/ref/*.java out/java/lang/ref/ -# cp upstream/gcc-3.3/src/libjava/java/lang/reflect/*.java out/java/lang/reflect/ + build/$(platform)/ibex.jar:upstream/install/share/java/libgcj-3.3.jar \ + -o build/pruned \ + `cat .natcalls` + rm -rf build/pruned/org/ibex/js/*; cp build/java/org/ibex/js/* build/pruned/org/ibex/js/ + rm build/pruned/java/lang/System.class cp upstream/gcc-3.3/src/libjava/java/lang/System.java build/pruned/java/lang/ - cd build/pruned; \ - for A in `find . -name \*.class -or -name \*.java`; do \ - echo compiling $$A....; \ - ../../upstream/install/bin/$(target)-gcj -w -c -fCLASSPATH=../../build/class $$A && \ + + rm build/pruned/gnu/gcj/runtime/FirstThread*.class + cp upstream/gcc-3.3/src/libjava/gnu/gcj/runtime/FirstThread.java build/pruned/gnu/gcj/runtime/ + + 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/ + + find build/pruned/gnu/java/locale/ -name 'LocaleInformation_*' -not -name 'LocaleInformation_en.class' -not -name 'LocaleInformation_en_US.class' -exec rm {} \; + +# cd build/pruned; fastjar cvf ../../tmp.jar . +# java -jar lib/jarg.jar -verbose -verboseufm -normlv -normsf -normsy -normin \ +# -normex -nornc -nornf -nornm -nobco tmp.jar +# cd build/pruned; fastjar xvf ../../tmp.jar + +# try oneshot compile/link +# --redefine-sym to merge errorthrowers? or do this in C++? +# --rename-section to try to merge Utf8 sections? + + cd build/pruned; \ + for A in `find . -name \*.class -or -name \*.java`; do \ + echo compiling $$A....; \ + ../../upstream/install/bin/$(target)-gcj \ + -fdata-sections -ffunction-sections -w -c -Os \ + -fCLASSPATH=../../build/$(platform)/ibex.jar $$A && \ (mkdir -p ../../build/$(platform)/`dirname $$A`; mv *.o ../../build/$(platform)/`dirname $$A`); \ done rm -f build/$(platform)/ibex.a cd upstream/gcc-3.3/build-$(target)/$(target)/libjava; \ $(shell pwd)/upstream/install/$(target)/bin/ar cq \ $(shell pwd)/build/$(platform)/ibex.a \ - `find . -name nat\*.o` \ + boehm.o defineclass.o exception.o \ + posix-threads.o posix.o prims.o resolve.o \ + `find . -name nat\*.o | grep -v JIS` \ `find . -name \*.o -not -name '*[A-Z]*'` \ - $(shell pwd)/build/$(platform)/org/ibex/plat/$(platform).cc.o \ `find $(shell pwd)/build/$(platform) -name \*.o` PATH=upstream/install/bin:$$PATH upstream/install/bin/$(target)-gcj \ --main=org.ibex.plat.$(platform) \ -Lupstream/install/$(target)/lib \ -Lupstream/install/lib \ + -ffunction-sections -fdata-sections -Os -w -fCLASSPATH=build/$(platform)/ibex.jar \ build/$(platform)/ibex.a \ upstream/jpeg-6b/build-$(target)/libjpeg.a \ $(link_flags) \ upstream/gcc-3.3/build-$(target)/$(target)/boehm-gc/.libs/libgcjgc.a \ -lz -ldl -lffi \ + -Wl,--noinhibit-exec,--gc-sections \ -o $@ +# linker +# --no-whole-archive,--relax,-O,2 +# +# -fomit-frame-pointer \ +# -fno-force-mem \ +# -fno-force-addr \ +# -fno-inline-functions \ +# -fnew-ra \ +# -fbranch-probabilities \ +# -finline-limit=1 \ +# -fno-schedule-insns \ +# -fno-optimize-sibling-calls \ +# -fno-if-conversion \ +# -fno-thread-jumps \ +# -fno-hosted \ ### Builtin Resources ############################################################################## diff --git a/Makefile.upstream b/Makefile.upstream index 45d1592..c93b9a2 100644 --- a/Makefile.upstream +++ b/Makefile.upstream @@ -72,7 +72,8 @@ configure_gcc-3.3 += --disable-shared --enable-static configure_binutils-2.13.2.1 += --disable-shared --enable-static configure_gcc-3.3_powerpc-apple-darwin += --enable-threads=posix --disable-hash-synchronization --disable-multilib configure_gcc-3.3_i686-pc-mingw32 += --enable-threads=win32 --enable-hash-synchronization -configure_gcc-3.3_i686-pc-linux-gnu += --enable-threads=posix --enable-hash-synchronization +configure_gcc-3.3_i686-pc-linux-gnu += --enable-threads=posix --disable-hash-synchronization +#configure_gcc-3.3_i686-pc-linux-gnu += --enable-threads=posix --enable-hash-synchronization configure_gcc-3.3_sparc-sun-solaris2.7 += --enable-threads=posix --disable-hash-synchronization --disable-multilib configure_WindowMaker-0.80.2_$(target) += --prefix=$(shell pwd)/upstream/install/$(target) diff --git a/src/org/ibex/plat/Linux.cc b/src/org/ibex/plat/Linux.cc index 9a9e324..e62a9ba 100644 --- a/src/org/ibex/plat/Linux.cc +++ b/src/org/ibex/plat/Linux.cc @@ -8,6 +8,8 @@ extern const char **_Jv_argv; 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)) { @@ -18,4 +20,5 @@ void org::ibex::plat::Linux::fixEnvironment() { printf("execvp() failed with error code %d\n", result); exit(-1); } + */ } diff --git a/src/org/ibex/util/BytecodePruner.java b/src/org/ibex/util/BytecodePruner.java new file mode 100644 index 0000000..f5dea9d --- /dev/null +++ b/src/org/ibex/util/BytecodePruner.java @@ -0,0 +1,384 @@ +package org.ibex.util; +import java.util.*; +import java.io.*; +import java.util.zip.*; +import org.apache.bcel.*; +import org.apache.bcel.generic.*; +import org.apache.bcel.classfile.*; +import org.apache.bcel.util.*; + +// Reachability rules: + +// - a constructor is reachable iff it is called +// - a static method is reachable iff it is called +// - a nonstatic method is reachable +// - a static field is reachable iff it is referenced +// - a nonstatic field is reachable iff it is referenced +// - is reachable iff any methods, static methods, fields, or constructors are reachable + +// - if a method is reachable, all the methods it overrides are reachable + +// FIXME: nonstatic method invocation or field access implies that object will be constructed (ie hint) + +public class BytecodePruner { + + // FIXME + public static SyntheticRepository repo = null; + + public static HashSet dest = new HashSet(); + + public static String outdir = "."; + + public void loadAllMethods(String classname) throws Exception { + visitJavaClass(repo.loadClass(classname)); + Method[] meths = repo.loadClass(classname).getMethods(); + for(int i=0; i= 3 && s[1].equals("-o")) { outdir = s[2]; start += 2; } + repo = SyntheticRepository.getInstance(new ClassPath(s[0])); + BytecodePruner bcp = new BytecodePruner(); + + for(int i=start; i")) good = true; + } else { + if (methods[i].getCode() != null) { + System.out.println(" pruning " + clazz.getClassName() + "." + methods[i].getName()); + MethodGen mg = new MethodGen(methods[i], clazz.getClassName(), newcpg); + mg.removeExceptions(); + InstructionList il = new InstructionList(); + mg.setInstructionList(il); + + InstructionHandle ih_0 = il.append(factory.createNew("java.lang.UnsatisfiedLinkError")); + il.append(InstructionConstants.DUP); + il.append(factory.createInvoke("java.lang.UnsatisfiedLinkError", + "", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); + il.append(InstructionConstants.ATHROW); + + mg.setMaxStack(); + mg.setMaxLocals(); + mg.removeExceptions(); + mg.removeLocalVariables(); + mg.removeExceptionHandlers(); + mg.removeLineNumbers(); + + cg.replaceMethod(methods[i], mg.getMethod()); + il.dispose(); + } + } + if ((clazz.getClassName().startsWith("gnu.java.locale.LocaleInformation") && + !clazz.getClassName().endsWith("LocaleInformation_en") && + !clazz.getClassName().endsWith("LocaleInformation") && + !clazz.getClassName().endsWith("LocaleInformation_en_US")) + || + (!good && + !clazz.isInterface() && + !clazz.isAbstract() && + !clazz.getClassName().endsWith("Error") && + !clazz.getClassName().endsWith("Exception") && + !clazz.getClassName().endsWith("Permission"))) { + + System.out.println("DROPPING " + clazz.getClassName()); + return; + } + new File(outdir + "/" + new File(clazz.getClassName().replace('.', '/')).getParent()).mkdirs(); + System.out.println("dumping " + clazz.getClassName()); + cg.getJavaClass().dump(outdir + "/" + clazz.getClassName().replace('.', '/') + ".class"); + } + + public JavaClass sig2class(String sig) throws Exception { + if (sig == null) return null; + while (sig.length() > 0 && (sig.charAt(0) == 'L' || sig.charAt(0) == '[')) { + if (sig.charAt(0) == 'L') sig = sig.substring(1, sig.length() - 1); + else if (sig.charAt(0) == '[') sig = sig.substring(1, sig.length()); + } + if (sig.length() <= 1) return null; + if (sig.equals("")) return null; + if (sig.startsWith(" 0 && (sig.charAt(0) == 'L' || sig.charAt(0) == '[')) { + if (sig.charAt(0) == 'L') sig = sig.substring(1, sig.length() - 1); + else if (sig.charAt(0) == '[') sig = sig.substring(1, sig.length()); + } + if (sig.length() <= 1) return; + if (sig.equals("")) return; + if (sig.startsWith("")) visitJavaMethod(clazz, methods[i]); + for(int i=0; i