You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2005/10/05 04:20:10 UTC
svn commit: r294974 [9/25] - in
/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm: ./ jchevm/
jchevm/doc/ jchevm/etc/ jchevm/include/ jchevm/java/ jchevm/java/org/
jchevm/java/org/dellroad/ jchevm/java/org/dellroad/jc/
jchevm/java/org/dellroad/...
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/escape/StackAllocTag.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/escape/StackAllocTag.java?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/escape/StackAllocTag.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/escape/StackAllocTag.java Tue Oct 4 19:19:16 2005
@@ -0,0 +1,57 @@
+
+//
+// Copyright 2005 The Apache Software Foundation or its licensors,
+// as applicable.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// $Id: StackAllocTag.java,v 1.3 2005/02/20 21:14:31 archiecobbs Exp $
+//
+
+package org.dellroad.jc.cgen.escape;
+
+import soot.tagkit.Tag;
+
+/**
+ * Tag for stack-allocatable allocations.
+ */
+public class StackAllocTag implements Tag {
+
+ private final static String NAME = "StackAllocTag";
+
+ int id;
+
+ public StackAllocTag(int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public byte[] getValue() {
+ return new byte[] {
+ (byte)(id >> 24), (byte)(id >> 16),
+ (byte)(id >> 8), (byte)id
+ };
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public String toString() {
+ return NAME;
+ }
+}
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/escape/package.html
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/escape/package.html?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/escape/package.html (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/escape/package.html Tue Oct 4 19:19:16 2005
@@ -0,0 +1,15 @@
+<html>
+<head>
+<title>
+Package description
+</title>
+</head>
+<body>
+
+<p>
+Classes used during escape analysis. When objects created during a method
+can be proven to not be referenced after that method returns, they may
+be allocated on the stack instead of the heap.
+
+</body>
+</html>
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/package.html
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/package.html?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/package.html (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/cgen/package.html Tue Oct 4 19:19:16 2005
@@ -0,0 +1,15 @@
+<html>
+<head>
+<title>
+Package description
+</title>
+</head>
+<body>
+
+<p>
+Classes used for JC's method of ELF object file generation by converting
+Java class files into C language source and header files and compiling
+them with GCC.
+
+</body>
+</html>
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/package.html
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/package.html?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/package.html (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/package.html Tue Oct 4 19:19:16 2005
@@ -0,0 +1,15 @@
+<html>
+<head>
+<title>
+Package description
+</title>
+</head>
+<body>
+
+<p>
+Classes used for the generation of ELF objects corresponding to
+Java classes for the JC virtual machine.
+</p>
+
+</body>
+</html>
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/DebugThread.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/DebugThread.java?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/DebugThread.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/DebugThread.java Tue Oct 4 19:19:16 2005
@@ -0,0 +1,52 @@
+
+//
+// Copyright 2005 The Apache Software Foundation or its licensors,
+// as applicable.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// $Id: DebugThread.java,v 1.1.1.1 2004/02/20 05:15:26 archiecobbs Exp $
+//
+
+package org.dellroad.jc.vm;
+
+/**
+ * JC debug thread. This thread sits and waits for SIGUSR1 signals.
+ * When one is received, it spits out the status and Java stack traces
+ * of all threads, as well as information about all class loaders.
+ */
+class DebugThread extends Thread {
+
+ DebugThread() {
+ super("debug");
+ setPriority(MIN_PRIORITY);
+ }
+
+ public void run() {
+ while (true) {
+ waitForInterrupt();
+ dumpDebugInfo();
+ }
+ }
+
+ // VM will call Thread.interrupt() on this thread when SIGUR1 rec'd
+ synchronized void waitForInterrupt() {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ }
+ }
+
+ static native void dumpDebugInfo();
+}
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/FinalizerThread.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/FinalizerThread.java?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/FinalizerThread.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/FinalizerThread.java Tue Oct 4 19:19:16 2005
@@ -0,0 +1,50 @@
+
+//
+// Copyright 2005 The Apache Software Foundation or its licensors,
+// as applicable.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// $Id: FinalizerThread.java,v 1.1.1.1 2004/02/20 05:15:26 archiecobbs Exp $
+//
+
+package org.dellroad.jc.vm;
+
+/**
+ * JC finalizer thread.
+ */
+class FinalizerThread extends Thread {
+
+ FinalizerThread() {
+ super("finalizer");
+ setPriority(MIN_PRIORITY);
+ }
+
+ public void run() {
+ while (true) {
+ waitForInterrupt();
+ finalizeObjects();
+ }
+ }
+
+ // VM will call Thread.interrupt() after each GC cycle
+ synchronized void waitForInterrupt() {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ }
+ }
+
+ static native void finalizeObjects();
+}
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/JarLoader.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/JarLoader.java?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/JarLoader.java (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/JarLoader.java Tue Oct 4 19:19:16 2005
@@ -0,0 +1,115 @@
+
+//
+// Copyright 2005 The Apache Software Foundation or its licensors,
+// as applicable.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// $Id: JarLoader.java,v 1.1.1.1 2004/02/20 05:15:26 archiecobbs Exp $
+//
+
+package org.dellroad.jc.vm;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+/**
+ * Helper class used to implement the "--jar" command line flag.
+ */
+public class JarLoader {
+
+ private JarLoader() {
+ }
+
+ /**
+ * Invoke the main class from a JAR file.
+ *
+ * @param args command line parameters with the JAR file
+ * name prepended as the first element of the array.
+ */
+ public static void main(String[] args) throws Throwable {
+
+ // Open JAR file
+ File jarfile = new File(args[0]);
+ JarFile jar;
+ try {
+ jar = new JarFile(jarfile);
+ } catch (IOException e) {
+ throw new RuntimeException("can't open ``"
+ + jarfile + "'': " + e.toString());
+ }
+
+ // Find manifest and read main class attribute
+ Manifest manifest;
+ try {
+ manifest = jar.getManifest();
+ } catch (IOException e) {
+ throw new RuntimeException("can't read manifest"
+ + " in ``" + jarfile + "'': " + e.toString());
+ }
+ if (manifest == null) {
+ throw new RuntimeException("no manifest found in ``"
+ + jarfile + "''");
+ }
+ String main = manifest.getMainAttributes().getValue(
+ Attributes.Name.MAIN_CLASS);
+ if (main == null) {
+ throw new RuntimeException("no ``"
+ + Attributes.Name.MAIN_CLASS + "'' attribute"
+ + " found in manifest of ``" + jarfile + "''");
+ }
+
+ // Prepend JAR file to class path
+ System.setProperty("java.class.path",
+ "file://" + jarfile.getAbsolutePath()
+ + System.getProperty("path.separator", ":")
+ + System.getProperty("java.class.path", "."));
+
+ // Find the main class
+ Class cl;
+ try {
+ cl = ClassLoader.getSystemClassLoader().loadClass(main);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("class ``" + main + "'' not"
+ + " found in JAR file ``" + jarfile + "''");
+ }
+
+ // Find the main() method
+ Method method;
+ try {
+ method = cl.getDeclaredMethod("main",
+ new Class[] { String[].class });
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException("no main() method found"
+ + " in class ``" + main + "''");
+ }
+
+ // Invoke main() method
+ String[] mainArgs = new String[args.length - 1];
+ System.arraycopy(args, 1, mainArgs, 0, mainArgs.length);
+ try {
+ method.invoke(null, new Object[] { mainArgs });
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("can't invoke main() method"
+ + " in class ``" + main + "'': " + e.toString());
+ } catch (InvocationTargetException e) {
+ throw e.getTargetException();
+ }
+ }
+}
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/Makefile.am
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/Makefile.am?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/Makefile.am (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/Makefile.am Tue Oct 4 19:19:16 2005
@@ -0,0 +1,7 @@
+## $Id: Makefile.am,v 1.1.1.1 2004/02/20 05:15:26 archiecobbs Exp $
+
+EXTRA_DIST= DebugThread.java \
+ FinalizerThread.java \
+ JarLoader.java \
+ package.html
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/package.html
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/package.html?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/package.html (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/java/org/dellroad/jc/vm/package.html Tue Oct 4 19:19:16 2005
@@ -0,0 +1,13 @@
+<html>
+<head>
+<title>
+Package description
+</title>
+</head>
+<body>
+
+<p>
+Classes used internally by the JC virtual machine.
+
+</body>
+</html>
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jc/Makefile.am
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jc/Makefile.am?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jc/Makefile.am (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jc/Makefile.am Tue Oct 4 19:19:16 2005
@@ -0,0 +1,10 @@
+## $Id: Makefile.am,v 1.4 2005/01/13 04:44:59 archiecobbs Exp $
+
+bin_PROGRAMS= jc
+
+jc_SOURCES= main.c
+
+jc_LDADD= ../libjc/libjc.la
+
+AM_CFLAGS= $(CFLAGS) @JC_CFLAGS@
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jc/main.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jc/main.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jc/main.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jc/main.c Tue Oct 4 19:19:16 2005
@@ -0,0 +1,44 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: main.c,v 1.2 2005/01/13 04:44:59 archiecobbs Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "jc_invoke.h"
+
+int
+main(int ac, char **av)
+{
+ int status = 0;
+
+ /* Invoke the JC VM */
+ switch (_jc_invoke(ac, (const char **)av, 1, vfprintf)) {
+ case _JC_RETURN_NORMAL:
+ break;
+ case _JC_RETURN_ERROR:
+ case _JC_RETURN_EXCEPTION:
+ status = 1;
+ break;
+ }
+
+ /* Done */
+ return status;
+}
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jsrc/Makefile.am
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jsrc/Makefile.am?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jsrc/Makefile.am (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/jsrc/Makefile.am Tue Oct 4 19:19:16 2005
@@ -0,0 +1,92 @@
+## $Id: Makefile.am,v 1.26 2005/05/16 14:23:05 archiecobbs Exp $
+
+jcbindir= $(bindir)
+jcincdir= $(includedir)/jc
+jcsrcdir= $(datadir)/jc/src
+jcobjdir= $(libdir)/jc/obj
+jcdir= $(datadir)/jc
+cpdir= $(CLASSPATH_HOME)/share/classpath
+
+CLASSPATH= $(top_srcdir)/java/jc.zip:$(cpdir)/glibj.zip:$(top_srcdir)/soot/sootclasses-$(SOOT_VERSION).jar:$(top_srcdir)/soot/jasminclasses-sable-$(JASMIN_VERSION).jar:$(top_srcdir)/soot/polyglot-$(POLYGLOT_VERSION).jar
+
+# Same as CLASSPATH but without classpath's core Java libraries
+VM_CPATH= $(top_srcdir)/java/jc.zip:$(top_srcdir)/soot/sootclasses-$(SOOT_VERSION).jar:$(top_srcdir)/soot/jasminclasses-sable-$(JASMIN_VERSION).jar:$(top_srcdir)/soot/polyglot-$(POLYGLOT_VERSION).jar
+
+COMPILEFLAGS= -c -O2 -pipe -g -fno-common -w -Wall -Waggregate-return \
+ -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment \
+ -Wformat -Wimplicit -Wmissing-declarations \
+ -Wmissing-prototypes -Wnested-externs -Wno-long-long \
+ -Wparentheses -Wpointer-arith -Wreturn-type -Wshadow \
+ -Wstrict-prototypes -Wswitch -Wtrigraphs -Wuninitialized \
+ -Wunused -Wwrite-strings -Wa,-W -I$(jcincdir) -I$(jcsrcdir)
+
+EXTRA_DIST= jsrc.tgz patterns
+
+##
+## Install pre-generated source files and compile them
+##
+install-exec-local: jsrc.tgz patterns
+ $(mkinstalldirs) $(DESTDIR)$(jcsrcdir)
+ $(mkinstalldirs) $(DESTDIR)$(jcobjdir)
+ @if [ "$(JC_PREGENERATED_SOURCES)" = "yes" ]; then \
+ if [ ! -d $(DESTDIR)$(jcsrcdir)/java ]; then \
+ echo '***' Installing C source files in $(DESTDIR)$(jcsrcdir); \
+ echo $(TAR) zxf $(srcdir)/jsrc.tgz -C $(DESTDIR)$(jcsrcdir); \
+ $(TAR) zxf $(srcdir)/jsrc.tgz -C $(DESTDIR)$(jcsrcdir); \
+ fi; \
+ echo '***' Generating ELF objects in $(DESTDIR)$(jcobjdir); \
+ if [ -x "$(JAVA)" ]; then \
+ $(DESTDIR)$(jcbindir)/jcgen -vmopt -mx400m \
+ -vmclasspath $(VM_CPATH) \
+ -jcclasspath $(CLASSPATH) \
+ -newsrcpath $(DESTDIR)$(jcsrcdir) \
+ -objdir $(DESTDIR)$(jcobjdir) \
+ -incdir $(DESTDIR)$(jcincdir) \
+ `cat $(srcdir)/patterns`; \
+ else \
+ find $(DESTDIR)$(jcsrcdir) -name '*.c' | while read CFILE; do \
+ OFILE=`echo $$CFILE | sed -e 's/\.c$$/.o/g'`; \
+ ODIR=`dirname $$OFILE`; \
+ [ -d "$$ODIR" ] || $(mkinstalldirs) $$ODIR; \
+ echo $(HOSTGCC) $(COMPILEFLAGS) -o $$OFILE $$CFILE; \
+ $(HOSTGCC) $(COMPILEFLAGS) -o $$OFILE $$CFILE; \
+ done; \
+ fi; \
+ fi
+
+uninstall-local:
+ rm -rf $(DESTDIR)$(jcsrcdir)
+ rm -rf $(DESTDIR)$(jcobjdir)
+
+##
+## Create and tar up pre-generated sources
+##
+jsrc.tgz:
+ @if [ ! -d patterns ]; then \
+ echo ${MAKE} patterns; \
+ ${MAKE} patterns; \
+ fi
+ @if [ ! -d sources ]; then \
+ echo mkdir sources; \
+ mkdir sources; \
+ fi
+ $(DESTDIR)$(jcbindir)/jcgen -N -vmopt -mx400m \
+ -newsrcpath sources `cat patterns`
+ ( cd sources && tar cf - * | gzip --best ) > $@
+
+##
+## Generate list of all packages containing installed classes
+##
+patterns:
+ @echo '***' Generating package list
+ @rm -f patterns patterns.1
+ @ZIPS=`echo $(CLASSPATH) | sed 's/:/ /g'`; \
+ for ZIP in $${ZIPS}; do \
+ $(UNZIP) -l $${ZIP} | grep '/.*\.class$$' \
+ | sed -e 's/^.* //g' -e 's,/.*$$,/%%,g' >> patterns.1; \
+ done; \
+ sort -u < patterns.1 > patterns; \
+ rm -f patterns.1
+
+CLEANFILES= sources objects patterns
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/Makefile.am
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/Makefile.am?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/Makefile.am (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/Makefile.am Tue Oct 4 19:19:16 2005
@@ -0,0 +1,109 @@
+## $Id: Makefile.am,v 1.14 2005/05/24 01:09:38 archiecobbs Exp $
+
+SUBDIRS= native arch
+
+lib_LTLIBRARIES= libjc.la
+
+libjc_la_LDFLAGS= -version-info @LIBRARY_VERSION@ -module
+
+# Standard source files
+libjc_la_SOURCES= \
+ array.c \
+ bootstrap.c \
+ c_support.c \
+ cf_parse.c \
+ cl_alloc.c \
+ class_bytes.c \
+ class_file.c \
+ class_loader.c \
+ class_object.c \
+ debug_line.c \
+ derive.c \
+ derive2.c \
+ elf.c \
+ exception.c \
+ fatal.c \
+ gc_final.c \
+ gc_root.c \
+ gc_scan.c \
+ heap.c \
+ init.c \
+ initialize.c \
+ instance.c \
+ interp.c \
+ invoke.c \
+ jc_invoke.c \
+ jni_invoke.c \
+ jni_native.c \
+ load.c \
+ lock.c \
+ misc.c \
+ mutex.c \
+ native_lib.c \
+ native_ref.c \
+ new.c \
+ os_functions.c \
+ prepare.c \
+ printf.c \
+ properties.c \
+ reflect.c \
+ resolve.c \
+ resolve2.c \
+ signals.c \
+ splay.c \
+ stack.c \
+ string.c \
+ tables.c \
+ thread.c \
+ utf.c \
+ verify.c \
+ vm.c \
+ vm_alloc.c \
+ zip.c
+
+# Java native method source files
+libjc_la_SOURCES+= native/gnu_classpath_VMStackWalker.c \
+ native/gnu_classpath_VMSystemProperties.c \
+ native/java_io_VMObjectStreamClass.c \
+ native/java_lang_VMClass.c \
+ native/java_lang_VMClassLoader.c \
+ native/java_lang_VMCompiler.c \
+ native/java_lang_VMObject.c \
+ native/java_lang_VMRuntime.c \
+ native/java_lang_VMSystem.c \
+ native/java_lang_VMThread.c \
+ native/java_lang_VMThrowable.c \
+ native/java_lang_reflect_Constructor.c \
+ native/java_lang_reflect_Field.c \
+ native/java_lang_reflect_Method.c \
+ native/org_dellroad_jc_JCFinder.c \
+ native/org_dellroad_jc_cgen_SootCodeGenerator.c \
+ native/org_dellroad_jc_vm_DebugThread.c \
+ native/org_dellroad_jc_vm_FinalizerThread.c
+
+# Architecture specific source files
+libjc_la_SOURCES+= arch/@JC_ARCH@/arch_elf_reloc.c \
+ arch/@JC_ARCH@/arch_functions.c
+
+# Header files
+libjc_la_SOURCES+= cf_parse.h \
+ definitions.h \
+ libjc.h \
+ inline.h \
+ structures.h \
+ zip.h
+
+AM_CFLAGS= $(CFLAGS) @JC_CFLAGS@
+AM_CFLAGS+= -D_AC_INCLUDEDIR=\"$(includedir)\"
+AM_CFLAGS+= -D_AC_DATADIR=\"$(datadir)\"
+AM_CFLAGS+= -D_AC_LIBDIR=\"$(libdir)\"
+AM_CFLAGS+= -D_AC_SYSCONFDIR=\"$(sysconfdir)\"
+AM_CFLAGS+= -D_JC_CLASSPATH_HOME=\"@CLASSPATH_HOME@\"
+AM_CFLAGS+= -DSOOT_VERSION=\"@SOOT_VERSION@\"
+AM_CFLAGS+= -DJASMIN_VERSION=\"@JASMIN_VERSION@\"
+AM_CFLAGS+= -DPOLYGLOT_VERSION=\"@POLYGLOT_VERSION@\"
+AM_CFLAGS+= -D_JC_BOOTSTRAP_JAVA=\"$(JAVA)\"
+AM_CFLAGS+= -D_JC_GNU_COMPILER=\"$(HOSTGCC)\"
+
+AM_CPPFLAGS= -I$(srcdir)/native -I$(srcdir)/arch
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/README
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/README?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/README (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/README Tue Oct 4 19:19:16 2005
@@ -0,0 +1,322 @@
+Subtleties
+==========
+
+There are lots of subtleties in the implementation of a Java VM.
+Here we attempt to discuss some of them.
+
+Basic stuff
+-----------
+
+A class is a Java concept represented by a class file. Classes can
+be either normal classes or interfaces. Classes exist even if there
+is no JVM to interpret them.
+
+A type is a runtime concept and is more general. All objects are
+instances of some type. Once a class is loaded, a type is created to
+represent its runtime manifestation. Note that the same class file
+may be loaded more than once (by different class loaders); each time
+the class is loaded a new type is created.
+
+All loaded classes are types but not the converse. The types which are
+not derived from loaded classes are the primitive types and the array
+types. Regardless, all types have instances of java.lang.Class associated
+with them. Each type contains a reference to the java.lang.Class object
+associated with that type.
+
+Confusion sometimes results because the word "class" is used when
+what is really meant is "type derived from a loaded class". Sometimes
+the phrase "class type" is used for clarity when referring to a runtime
+type which is neither a primitive nor array type.
+
+All objects are instances of some (non-primitive) type, and contain in
+their 2 word headers pointers to the vtable (virtual method dispath
+table) associated with that type (the other word is the lockword which
+contains various bits for locking the object, etc.).
+
+Bootstrap process
+-----------------
+
+During bootstrapping, creation of the Class objects that are associated
+with each loaded type is deferred until the "java.lang.Class" class has
+been loaded. Then we search the tree of already-loaded types and belatedly
+create their corresponding Class objects.
+
+Also, during bootstrap execution of arbitrary Java code (which includes
+class initialization) is disabled.
+
+No constructor is ever invoked for instances of java.lang.Class.
+
+See bootstrap.c for more details on the bootstrap sequence of events.
+Basic sequence of events:
+
+ - Disable creation of java.lang.Class instances and class initialization
+ - Load primitive types
+ - Load (but do not resolve, verify, or initialize) lots of other types
+ including Object, array types, reflection types, exceptions, etc.
+ - Find lots of useful fields, methods, and constructors in those types.
+ - Load java.lang.Class
+ - Go through all loaded types and create a java.lang.Class instance
+ for them (note: no constructor for java.lang.Class is ever invoked,
+ and class initialization is still disabled, so no Java code executes).
+ - Resolve java.lang.Object and java.lang.Class. This step must be after
+ the previous step so that ELF references to Class objects don't resolve
+ to NULL.
+ - Enable creation of java.lang.Class instances and class initialization
+ - Perform class initialization for java.lang.Class
+ - Create fallback exceptions (used to avoid recursion when an exception
+ is thrown while trying to create another instance of the same exception).
+
+Exceptions during bootstrap: 3 cases:
+
+ 1 'env' does not exist (no thread or vm context yet)
+ -> exception & message is printed out as an error when "posted"
+ 2 vm->initialization != NULL && !vm->initialization->may_execute
+ -> type & message stored in vm->initialization, printed when "caught"
+ 3 vm->initialization != NULL && vm->initialization->may_execute
+ -> recursive exception X before pre-instantiated exception X created?
+ 3a yes: type & message stored in vm->initialization, printed when "caught"
+ 3b no: exception is posted normally
+
+Code that is in the "bootstrap path" must not call _jc_retrieve_exception()
+because this function doesn't work before execution is enabled (because
+posted exceptions do not actually create any objects).
+
+Class loaders
+-------------
+
+There are two types of class loaders:
+
+ 1. The bootstrap class loader
+ 2. User-defined class loaders
+
+The bootstrap class loader (or "boot loader") is an internal JVM concept
+and does not have any corresponding ClassLoader object. This loader
+only knows how to read class files from the filesystem and from ZIP files
+(in this particular JVM implementation), and is used to load the first
+classes that are loaded during bootstrapping.
+
+User-defined class loaders are simply all loaders other than the boot
+loader, all of which are associated with instances of java.lang.ClassLoader.
+
+The system class loader (or "application class loader") is a user-defined
+loader. It is used e.g. to load the class specified on the command line.
+It is the loader returned by ClassLoader.getSystemClassLoader(). The VM has
+no explicit knowledge of it.
+
+People sometimes confuse the boot loader with the system loader, but they
+are completely different.
+
+With respect to a specific type, a class loader can be an "initiating
+loader" of that type. This basically means that someone successfully
+loaded the type using that loader, perhaps by invoking ClassLoader.loadClass().
+Another way to load a type using a specific class loader is to load
+another class with that class loader whose class file contiains a reference
+to the type.
+
+If a loader is an initiating loader for a type, it can also be a defining
+loader for that type. There is only one defining loader for each type,
+though there may be multiple initiating loaders. For "class types" the
+defining loader is either the boot loader or else it's the loader whose
+ClassLoader.defineClass() method was called to create the type's instance
+of java.lang.Class.
+
+Class loader memory
+-------------------
+
+Certain memory internal to the VM is associated with a particular
+class loader, and is only needed and used by that loader. Moreover,
+when/if such memory is freed, it may all be freed together at once
+(when the class loader and all its loaded classes are unloaded).
+
+Therefore for efficiency class loader memory is allocated on a stack
+who's top only grows in one direction (upward), until eventually
+the entire stack is freed at once.
+
+Examples of memory that can be allocated from class loader memory:
+
+0. Internal type structures for types defined by the loader
+1. java.lang.Class objects associated with types defined by the loader
+2. Virtual method dispatch tables associated with types defined by the loader
+3. ELF information associated with class types defined by the loader
+4. Native library information
+
+Class unloading
+---------------
+
+Classes may be unloaded when they are no longer reachable. Basically,
+this means the Class object itself is no longer reachable. Because
+from any Class object you can get the corresponding ClassLoader object,
+and vice-versa from any ClassLoader object you can obtain the Class
+objects associated with all its loaded classes, then it follows that
+a ClassLoader and all its loaded Class objects become unreachable at
+the same time.
+
+All references must be tracable at all times
+--------------------------------------------
+
+For GC to not free objects that are actually still in use, the GC
+scan needs to be able to find all in-use objects. For objects referenced
+via normal Java code, we guarantee this using the usual methods (i.e.,
+scanning the Java stacks of all live threads and Class variables of
+all loaded classes).
+
+The trickiness happens when objects are referenced only by internal
+C code and/or structures. We need a methodology for rigorously tracking
+these references. Here is the strategy.
+
+Each thread has a local native reference list which is explicitly
+scanned during each GC run. In addition, there is a global native
+reference list that is scanned during GC and used to hold non-thread
+specific references. All native references must be in one of these
+lists at any time a GC can possibly occur.
+
+References held only by a single thread (e.g., in a local variable)
+must be stored in that thread's local native reference list before
+any opportunity can be allowed to occur in which a GC run may be
+performed. Since GC can happen during any object allocation, or any
+time the current thread checks to see if another thread is trying to
+halt it, this means GC can happen during almost any function call.
+To be conservative, one should assume that the only safe time to call
+a function without storing local reference variables in the native
+reference list is when no functions are called while the reference
+is being used.
+
+If a reference is passed as a function parameter, we can assume that
+the calling function has already taken care of this.
+
+In addition, certain other references are explicitly scanned during GC:
+
+1. Any pending exception in each thread
+2. The java.lang.Thread object associated with each live thread
+
+Implicit references
+-------------------
+
+There are lots of "implicit" references in Java. E.g., from a Method
+object you can always get the corresponding Class object, but there's
+no actual field in the Method object that points to the class.
+Instead, a native method is used to find the Class object via
+internal references. Such references are called "implicit" references
+(which particular references are implicit depends on the way each
+VM is implemented, but there will always be some). Here are some
+other possible examples:
+
+ Class object -> Class object for its superclass
+ Class object -> Class object for its superinterfaces
+ Class object -> ClassLoader object (and vice-versa)
+ Field, Method, Constructor objects -> Class object
+ Class object -> its inner Class objects (and vice-versa)
+ Class object -> intern'd version of all String constants
+ Class object -> all Class objects corresponding to types explicitly
+ referenced by any field, method, or variable declaration
+
+We handle these "in bulk" as follows: all java.lang.Class objects are
+in class loader memory. We combine all the implicit references from
+all types defined by a loader into a single implicit references list
+for that loader, and then treat the whole class loader memory as a
+single "object" for the purposes of garbage collection, i.e., it only
+gets scanned once during the GC walk. Because types often have implicit
+references to other types defined by the same loader, this saves a lot
+of work because we don't need to follow any of those "loader internal"
+references during GC.
+
+ThreadDeathException
+====================
+
+Java allows a thread to asynchronously throw an exception in another
+thread. Doing this is rightfully deprecated and causes all sorts of
+race conditions. In any case, here is how we implement it:
+
+ %%%
+
+Class loading
+=============
+
+Class types are loaded and initialized using these steps:
+
+1. Class loading
+2. Class verification
+3. Class preparation
+4. Class linking
+5. Class initialization
+
+Loading
+-------
+
+The classfile byte[] array is stored in the JC compile directory
+hierarchy (the "classfile cache"). Any existing but different classfile
+is replaced.
+
+The byte[] array is parsed, resulting in a '_jc_classfile' structure.
+We do not bother to parse any bytecode.
+
+Then JC ensures that all other classfiles required to compile the
+C source for the class are in the classfile cache. This involves loading
+the class's superclasses and superinterfaces. It also involves attempting
+to load all other classes referred to by CONSTANT_Class entries in the
+class's constant pool which don't already exist in the classfile cache.
+Loading these classes may result in ClassCircularityErrors, for example
+if class C refers to class D and D's superclass is C, which are ignored.
+They are ignored because the real objective -- to load their classfiles
+into the classfile cache -- has been achieved.
+
+Then JC generates C source for the class and C header files for all of
+the aforementioned other classes, and then uses GCC to compile the source
+into an ELF object file. The loading of CONSTANT_Class classfiles ensures
+that Soot will not have to create any phantom classes.
+
+This ELF object file is then loaded by JC's internal ELF loader, all
+symbols which can be resolved within the file itself are resolved, and
+the class's '_jc_type' type structure is located. At this point the class
+is loaded.
+
+A class's loaded ELF image is described by a '_jc_elf' structure.
+This structure in turn includes a pointer to a '_jc_elf_info' structure,
+which contains all of the linking information associated with the ELF
+object, i.e., the ELF relocation and symbol tables.
+
+Verification
+------------
+
+Bytecode verification is not performed by JC, but if it was this is
+perhaps where it would be done.
+
+Verification may also be done during the generation of the C source
+file for the class. This may be much easier as it can be done in Java.
+
+Class preparation
+-----------------
+
+Static (i.e., class) fields that have constant initial values are
+initialized with the value proscribed in the class file. Only fields
+having primitive type or type String may have constant initial values.
+
+Linking
+-------
+
+This phase should really be called "Resolution" instead of "Linking".
+
+Linking involves resolving all remaining unresolved symbols in the class's
+loaded ELF image. These will be references to symbols external to the ELF
+file itself, such as references to other classes and JC support functions.
+Linking may involve trigger loading of these other classes.
+
+Note that if a class C contains a symbol referring to class D, then
+assuming D has been loaded, it is not necessary for D's ELF linking
+information (the '_jc_elf_info' structure) to exist for C to link to D,
+because the locations of all of D's fields and methods can be computed
+solely from D's '_jc_type' type descriptor.
+
+Therefore, at this point the class's '_jc_elf' and '_jc_classfile'
+structures may be freed as they are no longer needed.
+
+Initialization
+--------------
+
+The static "<clinit>" method of the class is executed, if any.
+Class initialization is triggered the first time an object of the
+class is instantiated, any static method is called, or any static
+field of the class is accessed.
+
+Classes loaded during bootstrap may not have "<clinit>" methods.
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/Makefile.am
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/Makefile.am?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/Makefile.am (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/Makefile.am Tue Oct 4 19:19:16 2005
@@ -0,0 +1,8 @@
+## $Id: Makefile.am,v 1.1.1.1 2004/02/20 05:15:49 archiecobbs Exp $
+
+noinst_HEADERS= arch_definitions.h \
+ arch_libjc.h \
+ arch_structures.h
+
+SUBDIRS= i386
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_definitions.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_definitions.h?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_definitions.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_definitions.h Tue Oct 4 19:19:16 2005
@@ -0,0 +1,136 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: arch_definitions.h,v 1.9 2005/05/14 22:20:17 archiecobbs Exp $
+ */
+
+#ifndef _ARCH_DEFINITIONS_H_
+#define _ARCH_DEFINITIONS_H_
+
+/************************************************************************
+ * Overview *
+ ************************************************************************/
+
+/*
+
+This purpose of this file is to define operating system and/or architecture
+specific values. After defining some generic, overridable values, this file
+includes the appropriate architecture-specific definitions header file.
+
+Here is a summary of things that need to be defined by this file or
+an included file:
+
+String constants
+----------------
+
+ _JC_PATH_SEPARATOR String that separates paths in a search path
+ _JC_FILE_SEPARATOR String that separates directories in a pathname
+ _JC_LINE_SEPARATOR String that marks the end of line in a text file
+
+ _JC_LIBRARY_FMT printf(3) format string converting a simple native
+ library name into a system library filename
+ _JC_TEMP_DIR Operating system directory for temporary files
+
+ _JC_STACK_MINIMUM Default minimum thread stack size (zero for none)
+ _JC_STACK_MAXIMUM Default maximum thread stack size (zero for none)
+ _JC_STACK_DEFAULT Default thread stack size (should not be zero)
+
+ _JC_DEFAULT_HEAP_SIZE
+ Default heap size
+ _JC_DEFAULT_LOADER_SIZE
+ Default class loader memory size
+ _JC_DEFAULT_HEAP_GRANULARITY
+ Default heap block size granularity factor: a number
+ from 0 to 99, where higher is more granular. For a
+ value X, each block size is at least (100-x)% bigger
+ than the next bigger block size.
+
+ The last five strings must contain simple numbers (not expressions)
+ that can be converted into numerical values via stroull().
+
+Numerical constants
+-------------------
+
+ _JC_PAGE_SHIFT log_2 of the size of a VM page (as returned by
+ getpagesize(3)). E.g., 4096 byte pages -> 12.
+
+ _JC_ELF_CLASS ELF object class
+ _JC_ELF_DATA ELF object data format
+ _JC_ELF_MACHINE ELF object machine type
+
+ _JC_STACK_ALIGN Runtime stack alignment
+
+ _JC_BIG_ENDIAN 1 if big endian, 0 if little endian
+
+Other definitions
+-----------------
+
+ _JC_REGISTER_OFFS Initializer for an array of integers representing
+ the offsets into a mcontext_t structure where the
+ registers live. Used for garbage collection.
+
+*/
+
+/************************************************************************
+ * Generic O/S dependent but architecture independent stuff *
+ ************************************************************************/
+
+ /******** Generic (override as necessary) *********/
+
+#define _JC_PATH_SEPARATOR ":"
+#define _JC_FILE_SEPARATOR "/"
+#define _JC_LINE_SEPARATOR "\n"
+#define _JC_TEMP_DIR "/var/tmp"
+#define _JC_LIBRARY_FMT "lib%s.so"
+
+#define _JC_STACK_MINIMUM "0"
+#define _JC_STACK_MAXIMUM "0"
+#define _JC_STACK_DEFAULT "262144" /* 256K */
+
+#define _JC_DEFAULT_HEAP_SIZE "134217728" /* 128M */
+#define _JC_DEFAULT_LOADER_SIZE "33554432" /* 32M */
+#define _JC_DEFAULT_HEAP_GRANULARITY "85"
+
+/************************************************************************
+ * Architecture-specific definitions *
+ ************************************************************************/
+
+/*
+ * The following arch-specific definitions remain:
+ *
+ * _JC_PAGE_SHIFT
+ * _JC_ELF_CLASS
+ * _JC_ELF_DATA
+ * _JC_ELF_MACHINE
+ */
+
+#if defined(__i386__)
+#include "i386/i386_definitions.h"
+#elif defined(__sparc__)
+#include "sparc/sparc_definitions.h"
+#elif defined(__alpha__)
+#include "alpha/alpha_definitions.h"
+#elif defined(__ia64__)
+#include "ia64/ia64_definitions.h"
+#elif defined(__powerpc__)
+#include "powerpc/powerpc_definitions.h"
+#else
+#error "Unsupported architecture for architecture-specific definitions"
+#endif
+
+#endif /* _ARCH_DEFINITIONS_H_ */
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_libjc.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_libjc.h?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_libjc.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_libjc.h Tue Oct 4 19:19:16 2005
@@ -0,0 +1,217 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: arch_libjc.h,v 1.7 2005/07/10 21:03:55 archiecobbs Exp $
+ */
+
+#ifndef _ARCH_LIBJC_H_
+#define _ARCH_LIBJC_H_
+
+/************************************************************************
+ * Overview *
+ ************************************************************************/
+
+/*
+
+This purpose of this file is to declare and/or define architecture-specific
+functions. Inline functions must be defined as "extern inline".
+
+Here is a summary of functions that need to be defined by this file or
+an included file:
+
+ int
+ _jc_compare_and_swap(volatile _jc_word *word, _jc_word old, _jc_word new)
+
+ A function that performs the following operation atomically:
+
+ if (*pword == old) {
+ *pword = new;
+ return JNI_TRUE;
+ } else
+ return JNI_FALSE;
+
+ int
+ _jc_build_trampoline(u_char *code, _jc_method *method, const void *func)
+
+ A function that builds a trampoline at location pointed to by "code".
+ The trampoline will be invoked using normal JCNI calling conventions
+ appropriate for "method". The trampoline should do the following:
+
+ 1. Set env->interp to "method".
+ 2. Invoke "func" with the same parameters.
+ 3. Return what "func" returns.
+
+ "func" is invoked using normal calling conventions as if declared:
+
+ rtype func(_jc_env *env, ...)
+
+ where "rtype" is the return type appropriate for "method". Note
+ that normal C promotion applies: int types smaller than int must
+ be promoted to int, and float must be promoted to double.
+
+ _jc_build_trampoline() should return the trampoline's length.
+
+ "code" may be NULL, in which case just the length of the trampoline
+ should be returned. Otherwise, "code" will point to aligned memory.
+
+ The generated code does not need to be position-independent.
+
+ void
+ _jc_dynamic_invoke(const void *func, int jcni, int nparams,
+ const u_char *ptypes, int nwords, _jc_word *words, _jc_value *retval)
+
+ Dynamically constructed C function call. Should invoke the C function
+ "func" with supplied parameters. Return value should be stored in
+ *retval. Must not break the stack frame pointer chain. "ptypes" has
+ length "nparams" + 1 giving the parameter and return value types.
+ "words" points to the Java style parameters (i.e., 2 for long/double).
+
+ 'jcni' is non-zero for JNCI functions, zero for normal C functions.
+ Can be ignored if JNCI calling conventions are the same as normal
+ calling conventions for a particular architecture.
+
+ void
+ _jc_iflush(const void *mem, size_t len)
+
+ This function should flush the CPU instruction cache for
+ the given range of memory (if appropriate), as the memory
+ contains newly loaded executable code.
+
+Stack Functions
+---------------
+
+The following functions all manipulate '_jc_stack_frame' objects.
+A stack frame object is associated with a specific function invocation.
+Typically a '_jc_stack_frame' is just functionA()'s saved frame pointer.
+
+These functions must not call any other functions that could allocate
+memory, etc. See "arch/arch_structures.h".
+
+ void
+ _jc_stack_frame_init(_jc_stack_frame *framep)
+
+ Initialize 'frame' to the invalid stack frame value.
+
+ jboolean
+ _jc_stack_frame_valid(_jc_stack_frame frame)
+
+ Returns JNI_TRUE if the frame is not the invalid frame.
+
+ jboolean
+ _jc_stack_frame_equal(_jc_stack_frame frame1, _jc_stack_frame frame2)
+
+ Returns JNI_TRUE if the two frames are the same.
+
+ void
+ _jc_stack_frame_current(_jc_stack_frame *framep)
+
+ Initialize 'frame' to refer to the stack frame associated with
+ the invocation from functionA() -> functionB(), where functionB()
+ is the function calling _jc_stack_frame_current().
+
+ void
+ _jc_stack_frame_next(_jc_stack_frame *frame, const void **pcp)
+
+ Advance 'frame' to the frame one deeper on the stack
+ and update *pcp to be the PC address in the deeper frame.
+
+ const void *
+ _jc_stack_frame_sp(_jc_stack_frame frame)
+
+ Convert a stack frame into a stack address. If 'frame' is associated
+ with functionA(), then the stack address is only required to include
+ the stack variables of the fuction that invoked functionA() (but not
+ functionA() itself). The pointer must be aligned to _JC_STACK_ALIGN.
+
+ const void *
+ _jc_mcontext_sp(const mcontext_t *mctx)
+
+ Returns the saved stack pointer from an mcontext_t structure.
+
+ const void *
+ _jc_mcontext_pc(const mcontext_t *mctx)
+
+ Returns the saved PC from an mcontext_t structure. This should
+ correspond to the PC address in functionA() where functionA() is
+ the function that called getcontext() or caught the signal.
+
+ _jc_stack_frame
+ _jc_mcontext_frame(const mcontext_t *mctx)
+
+ Returns the stack frame from an mcontext_t structure. This
+ should correspond to functionA() calling functionB(), where
+ functionA() is the function that called getcontext() or
+ caught the signal.
+
+ const void *
+ _jc_signal_fault_address(int sig_num, siginfo_t *info, ucontext_t *uctx)
+
+ This function is invoked during signal handling. The three
+ parameters are copied unchanged by the POSIX SIG_INFO style
+ handler. This function should return the fault address, i.e.,
+ the illegal memory address which could not be accessed, if any.
+
+*/
+
+/************************************************************************
+ * Function declarations *
+ ************************************************************************/
+
+/* Misc functions */
+extern int _jc_compare_and_swap(volatile _jc_word *word,
+ _jc_word old, _jc_word new);
+extern void _jc_iflush(const void *mem, size_t len);
+extern int _jc_build_trampoline(u_char *code, _jc_method *method,
+ const void *func);
+extern void _jc_dynamic_invoke(const void *func, int jcni,
+ int nparams, const u_char *ptypes, int nwords,
+ _jc_word *words, _jc_value *retval);
+
+/* Stack frame functions */
+extern void _jc_stack_frame_init(_jc_stack_frame *framep);
+extern void _jc_stack_frame_next(_jc_stack_frame *prev,
+ const void **pcp);
+extern jboolean _jc_stack_frame_valid(_jc_stack_frame frame);
+extern jboolean _jc_stack_frame_equal(_jc_stack_frame frame1,
+ _jc_stack_frame frame2);
+extern const void *_jc_stack_frame_sp(_jc_stack_frame frame);
+extern const void *_jc_mcontext_sp(const mcontext_t *mctx);
+extern const void *_jc_mcontext_pc(const mcontext_t *mctx);
+extern _jc_stack_frame _jc_mcontext_frame(const mcontext_t *mctx);
+extern const void *_jc_signal_fault_address(int sig_num,
+ siginfo_t *info, ucontext_t *uctx);
+
+/************************************************************************
+ * Architecture-specific functions *
+ ************************************************************************/
+
+#if defined(__i386__)
+#include "i386/i386_libjc.h"
+#elif defined(__sparc__)
+#include "sparc/sparc_libjc.h"
+#elif defined(__alpha__)
+#include "alpha/alpha_libjc.h"
+#elif defined(__ia64__)
+#include "ia64/ia64_libjc.h"
+#elif defined(__powerpc__)
+#include "powerpc/powerpc_libjc.h"
+#else
+#error "Unsupported architecture for architecture-specific functions"
+#endif
+
+#endif /* _ARCH_LIBJC_H_ */
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_structures.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_structures.h?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_structures.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/arch_structures.h Tue Oct 4 19:19:16 2005
@@ -0,0 +1,73 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: arch_structures.h,v 1.2 2004/12/14 03:03:25 archiecobbs Exp $
+ */
+
+#ifndef _ARCH_STRUCTURES_H_
+#define _ARCH_STRUCTURES_H_
+
+/************************************************************************
+ * Overview *
+ ************************************************************************/
+
+/*
+
+This purpose of this file is to define architecture-specific structures.
+Here is a summary of structures that need to be defined by this file or
+an included file:
+
+Stack Frames
+------------
+
+This file must define a '_jc_stack_frame' type, an opaque type
+representing a stack frame, with the following properties:
+
+ - A stack frame is always associated with a function invocation,
+ i.e., there is a calling function and a called function.
+ - A stack frame is cabable of providing the return address in the
+ calling function, i.e., the address of the next instruction to
+ execute in the calling function after the called function returns.
+ - A stack frame does not need to remain valid after the calling
+ function returns.
+ - Two stack frames can be compared for equality, where equality means
+ they refer to the same caller -> callee invocation on the stack.
+ - There must be an 'invalid' value not equal to any other value.
+ - It is possible to get the 'current' stack frame.
+
+*/
+
+/************************************************************************
+ * Architecture-specific structures *
+ ************************************************************************/
+
+#if defined(__i386__)
+#include "i386/i386_structures.h"
+#elif defined(__sparc__)
+#include "sparc/sparc_structures.h"
+#elif defined(__alpha__)
+#include "alpha/alpha_structures.h"
+#elif defined(__ia64__)
+#include "ia64/ia64_structures.h"
+#elif defined(__powerpc__)
+#include "powerpc/powerpc_structures.h"
+#else
+#error "Unsupported architecture for architecture-specific structures"
+#endif
+
+#endif /* _ARCH_STRUCTURES_H_ */
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/.cvsignore
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/.cvsignore?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/.cvsignore (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/.cvsignore Tue Oct 4 19:19:16 2005
@@ -0,0 +1 @@
+*.So
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/Makefile.am
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/Makefile.am?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/Makefile.am (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/Makefile.am Tue Oct 4 19:19:16 2005
@@ -0,0 +1,8 @@
+## $Id: Makefile.am,v 1.1.1.1 2004/02/20 05:15:49 archiecobbs Exp $
+
+noinst_HEADERS= arch_elf_reloc.c \
+ arch_functions.c \
+ i386_definitions.h \
+ i386_libjc.h \
+ i386_structures.h
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/arch_elf_reloc.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/arch_elf_reloc.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/arch_elf_reloc.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/arch_elf_reloc.c Tue Oct 4 19:19:16 2005
@@ -0,0 +1,74 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: arch_elf_reloc.c,v 1.2 2004/07/05 21:03:28 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+
+static const char *_jc_elf_reloc_names[11] = {
+ "R_386_NONE",
+ "R_386_32",
+ "R_386_PC32",
+ "R_386_GOT32",
+ "R_386_PLT32",
+ "R_386_COPY",
+ "R_386_GLOB_DAT",
+ "R_386_JMP_SLOT",
+ "R_386_RELATIVE",
+ "R_386_GOTOFF",
+ "R_386_GOTPC",
+};
+#define NUM_RELOC_NAMES \
+ (sizeof(_jc_elf_reloc_names) / sizeof(*_jc_elf_reloc_names))
+
+/*
+ * Apply an i386 ELF relocation.
+ *
+ * None of the i386 ELF relocations use the addend field, so we ignore it.
+ *
+ * Any exceptions are stored, not posted.
+ */
+jint
+_jc_elf_arch_reloc(_jc_env *env, const char *path, char *target_base,
+ Elf_Addr target_offset, Elf_Word type, Elf_Addr value, Elf_Off addend)
+{
+ Elf_Addr *const target_addr = (Elf_Addr *)(target_base + target_offset);
+
+ switch (type) {
+ case R_386_NONE:
+ return JNI_OK;
+ case R_386_32:
+ *target_addr += value;
+ return JNI_OK;
+ case R_386_PC32:
+ *target_addr += value - (Elf_Addr)target_addr;
+ return JNI_OK;
+ case R_386_GLOB_DAT:
+ *target_addr = value;
+ return JNI_OK;
+ case R_386_RELATIVE:
+ *target_addr += (Elf_Addr)target_base;
+ return JNI_OK;
+ default:
+ _JC_EX_STORE(env, LinkageError, "unsupported ELF relocation"
+ " type `%s' in `%s'", (type < NUM_RELOC_NAMES) ?
+ _jc_elf_reloc_names[type] : "?", path);
+ return JNI_ERR;
+ }
+}
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/arch_functions.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/arch_functions.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/arch_functions.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/arch_functions.c Tue Oct 4 19:19:16 2005
@@ -0,0 +1,478 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: arch_functions.c,v 1.4 2005/07/10 21:03:55 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+
+int
+_jc_build_trampoline(u_char *code, _jc_method *method, const void *func)
+{
+ u_char buf[100 + 14 * method->num_parameters];
+ u_char *pc;
+
+ /* Sanity check */
+ _JC_ASSERT(_JC_OFFSETOF(_jc_env, interp) < 0x80);
+
+ /* Handle length only computation */
+ if (code == NULL)
+ code = buf;
+ pc = code;
+
+#if !_JC_I386_REGPARM
+ /* Load "env", the first parameter, into %eax */
+ *pc++ = 0x8b; /* mov 0x4(%esp),%eax */
+ *pc++ = 0x44;
+ *pc++ = 0x24;
+ *pc++ = 0x04;
+
+ /* Set env->interp = method */
+ *pc++ = 0xc7; /* mov METHOD,OFFSET(%eax) */
+ *pc++ = 0x40;
+ *pc++ = _JC_OFFSETOF(_jc_env, interp);
+ memcpy(pc, &method, 4);
+ pc += 4;
+
+ /* Jump to function entry point */
+ *pc++ = 0xe9; /* jmp FUNCTION */
+ func = (void *)((jint)func - (jint)(pc + 4));
+ memcpy(pc, &func, 4);
+ pc += 4;
+#else
+ {
+ u_char ptypebuf[2];
+ u_char offsets[4];
+ u_char isfloat[3];
+ const u_char *ptypes;
+ int nparams2;
+ int nparams;
+ int offset;
+ int pnum;
+
+ /* Count total number of parameter words */
+ nparams2 = 1; /* "env" */
+ if (!_JC_ACC_TEST(method, STATIC))
+ nparams2++; /* "this" */
+ nparams2 += method->num_parameters;
+ for (pnum = 0; pnum < method->num_parameters; pnum++) {
+ if (_jc_dword_type[method->param_ptypes[pnum]])
+ nparams2++;
+ }
+
+ /* Get types of parameter words 1 and 2 (we know type for 0, "env") */
+ if (_JC_ACC_TEST(method, STATIC)) {
+ ptypes = method->param_ptypes;
+ nparams = method->num_parameters;
+ } else {
+ ptypebuf[0] = _JC_TYPE_REFERENCE; /* this */
+ ptypebuf[1] = method->param_ptypes[0]; /* first parameter */
+ ptypes = ptypebuf;
+ nparams = method->num_parameters + 1;
+ }
+
+ /* Prologue */
+ *pc++ = 0x55; /* push %ebp */
+ *pc++ = 0x89; /* mov %esp,%ebp */
+ *pc++ = 0xe5;
+
+ /* Calculate offsets to parameter words not passed in registers */
+ memset(&offsets, 0, sizeof(offsets));
+ memset(&isfloat, 0, sizeof(isfloat));
+ offset = 2; /* skip %ebp, return address */
+ if (nparams >= 1) {
+ switch (ptypes[0]) {
+ case _JC_TYPE_DOUBLE:
+ offsets[1] = offset++;
+ offsets[2] = offset++;
+ break;
+ case _JC_TYPE_FLOAT:
+ offsets[1] = offset++;
+ isfloat[1] = JNI_TRUE;
+ if (nparams >= 2) {
+ switch (ptypes[1]) {
+ case _JC_TYPE_DOUBLE:
+ case _JC_TYPE_LONG:
+ offsets[2] = offset++;
+ break;
+ case _JC_TYPE_FLOAT:
+ offsets[2] = offset++;
+ isfloat[2] = JNI_TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case _JC_TYPE_LONG:
+ break;
+ default:
+ if (nparams >= 2) {
+ switch (ptypes[1]) {
+ case _JC_TYPE_DOUBLE:
+ case _JC_TYPE_LONG:
+ offsets[2] = offset++;
+ break;
+ case _JC_TYPE_FLOAT:
+ offsets[2] = offset++;
+ isfloat[2] = JNI_TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ }
+ offsets[3] = offset++;
+ }
+
+ /* Copy 4th and later parameter words into parameter array */
+ if (nparams2 >= 4) {
+ int pword;
+
+ /* Save %eax */
+ *pc++ = 0x50; /* push %eax */
+
+ /* Copy 4th and later parameter words */
+ offset = (offsets[3] + (nparams2 - 4)) * 4;
+ pnum = method->num_parameters - 1;
+ if (_jc_dword_type[method->param_ptypes[pnum]])
+ pnum = -pnum;
+ for (pword = nparams2 - 1; pword >= 3; pword--, offset -= 4) {
+
+ /* Load parameter word from stack and then push it */
+ if (pnum >= 0
+ && method->param_ptypes[pnum] == _JC_TYPE_FLOAT) {
+
+ /* Load float */
+ if (offset < 0x80) {
+ /* flds 0xOFFSET(%ebp) */
+ *pc++ = 0xd9;
+ *pc++ = 0x45;
+ *pc++ = offset;
+ } else {
+ /* flds 0xOFFSET(%ebp) */
+ *pc++ = 0xd9;
+ *pc++ = 0x85;
+ memcpy(pc, &offset, 4);
+ pc += 4;
+ }
+
+ /* Push double */
+ *pc++ = 0x83; /* sub 0x8,%esp */
+ *pc++ = 0xec;
+ *pc++ = 0x8;
+ *pc++ = 0xdd; /* fstpl (%esp,1) */
+ *pc++ = 0x1c;
+ *pc++ = 0x24;
+ } else {
+ if (offset < 0x80) {
+ /* mov 0xOFFSET(%ebp),%eax */
+ *pc++ = 0x8b;
+ *pc++ = 0x45;
+ *pc++ = offset;
+ } else {
+ /* mov 0xOFFSET(%ebp),%eax */
+ *pc++ = 0x8b;
+ *pc++ = 0x85;
+ memcpy(pc, &offset, 4);
+ pc += 4;
+ }
+ *pc++ = 0x50; /* push %eax */
+ }
+
+ /* Keep track of corresponding parameter index */
+ if (pnum < 0) /* was second word of long/double */
+ pnum = -pnum;
+ else if (_jc_dword_type[method->param_ptypes[--pnum]])
+ pnum = -pnum;
+ }
+
+ /* Restore %eax */
+ *pc++ = 0x8b; /* mov -4(%ebp),%eax */
+ *pc++ = 0x45;
+ *pc++ = 0xfc;
+ }
+
+ /* Recall 3rd parameter word from stack (if necessary) and push */
+ if (nparams2 >= 3) {
+ if (isfloat[2]) {
+ *pc++ = 0xd9; /* flds 0xNN(%ebp) */
+ *pc++ = 0x45;
+ *pc++ = offsets[2] * 4;
+ *pc++ = 0x83; /* sub 0x8,%esp */
+ *pc++ = 0xec;
+ *pc++ = 0x8;
+ *pc++ = 0xdd; /* fstpl (%esp,1) */
+ *pc++ = 0x1c;
+ *pc++ = 0x24;
+ } else {
+ if (offsets[2] > 0) {
+ *pc++ = 0x8b; /* mov 0xNN(%ebp),%ecx */
+ *pc++ = 0x4d;
+ *pc++ = offsets[2] * 4;
+ }
+ *pc++ = 0x51; /* push %ecx */
+ }
+ }
+
+ /* Recall 2nd parameter word from stack (if necessary) and push */
+ if (nparams2 >= 2) {
+ if (isfloat[1]) {
+ *pc++ = 0xd9; /* flds 0xNN(%ebp) */
+ *pc++ = 0x45;
+ *pc++ = offsets[1] * 4;
+ *pc++ = 0x83; /* sub 0x8,%esp */
+ *pc++ = 0xec;
+ *pc++ = 0x8;
+ *pc++ = 0xdd; /* fstpl (%esp,1) */
+ *pc++ = 0x1c;
+ *pc++ = 0x24;
+ } else {
+ if (offsets[1] > 0) {
+ *pc++ = 0x8b; /* mov 0xNN(%ebp),%edx */
+ *pc++ = 0x55;
+ *pc++ = offsets[1] * 4;
+ }
+ *pc++ = 0x52; /* push %edx */
+ }
+ }
+
+ /* Push "env" (first parameter) onto the stack */
+ *pc++ = 0x50; /* push %eax */
+
+ /* Set env->interp = method */
+ *pc++ = 0xc7; /* mov METHOD,OFFSET(%eax) */
+ *pc++ = 0x40;
+ *pc++ = _JC_OFFSETOF(_jc_env, interp);
+ memcpy(pc, &method, 4);
+ pc += 4;
+
+ /* Call function */
+ *pc++ = 0xe8; /* call func */
+ func = (void *)((jint)func - (jint)(pc + 4));
+ memcpy(pc, &func, 4);
+ pc += 4;
+
+ /* Epilogue */
+ *pc++ = 0xc9; /* leave */
+ *pc++ = 0xc3; /* ret */
+ }
+#endif
+
+ /* Done */
+ return pc - code;
+}
+
+#if _JC_I386_REGPARM
+
+/*
+ * We use __attribute__ ((regparm(3))) which places the first three
+ * words of parameters into %eax, %edx, and %ecx (in that order).
+ * Exceptions are jlongs that would be split in half by %ecx, and
+ * jfloats and jdoubles, which are always pushed on the stack (though
+ * they also still "use" the corresponding registers).
+ */
+
+void
+_jc_dynamic_invoke(const void *func, int jcni, int nparams,
+ const u_char *ptypes, int nwords, _jc_word *words, _jc_value *retval)
+{
+ _jc_word twords[3];
+ u_char push[4];
+ int i;
+ int w;
+
+ /* We require 'words' array to have at least three elements */
+ if (nwords < 3) {
+ memcpy(twords, words, nwords * sizeof(*words));
+ words = twords;
+ }
+
+ /* For normal calling conventions, all parameters are pushed */
+ if (!jcni) {
+ memset(push, 1, sizeof(push));
+ goto push_args;
+ }
+
+ /*
+ * Determine which of the first three words need to be pushed
+ * onto the stack. This follows the GCC calling conventions for
+ * __attribute__ ((regparm(3))).
+ */
+ for (i = w = 0; i < nparams && w < 3; i++) {
+ switch (ptypes[i]) {
+ case _JC_TYPE_FLOAT: /* always push floats */
+ push[w++] = 1;
+ break;
+ case _JC_TYPE_DOUBLE: /* always push doubles */
+ push[w++] = 1;
+ push[w++] = 1;
+ break;
+ case _JC_TYPE_LONG: /* just don't break a long in half */
+ if (w == 2) {
+ push[w++] = 1;
+ push[w++] = 1;
+ } else {
+ push[w++] = 0;
+ push[w++] = 0;
+ }
+ break;
+ default: /* everything else goes in registers */
+ push[w++] = 0;
+ break;
+ }
+ }
+
+push_args:
+ /* Push parameters onto the stack */
+ for (i = nwords; --i >= 0; ) {
+ if (i >= 3 || push[i])
+ asm volatile ("pushl %0" : : "m" (words[i]) : "sp");
+ }
+
+ /*
+ * Load registers with the first three parameter words then invoke
+ * the function. For simplicity, and to avoid adding code which could
+ * overwrite them, we always load all three registers.
+ */
+ switch (ptypes[nparams]) {
+ case _JC_TYPE_BOOLEAN:
+ asm volatile ("movl %0,%%ecx" : : "m" (words[2]) : "sp", "cx");
+ asm volatile ("movl %0,%%edx" : : "m" (words[1]) : "sp", "dx");
+ asm volatile ("movl %0,%%eax" : : "m" (words[0]) : "sp", "ax");
+ retval->z = (*(jboolean (*)())func)();
+ break;
+ case _JC_TYPE_BYTE:
+ asm volatile ("movl %0,%%ecx" : : "m" (words[2]) : "sp", "cx");
+ asm volatile ("movl %0,%%edx" : : "m" (words[1]) : "sp", "dx");
+ asm volatile ("movl %0,%%eax" : : "m" (words[0]) : "sp", "ax");
+ retval->b = (*(jbyte (*)())func)();
+ break;
+ case _JC_TYPE_CHAR:
+ asm volatile ("movl %0,%%ecx" : : "m" (words[2]) : "sp", "cx");
+ asm volatile ("movl %0,%%edx" : : "m" (words[1]) : "sp", "dx");
+ asm volatile ("movl %0,%%eax" : : "m" (words[0]) : "sp", "ax");
+ retval->c = (*(jchar (*)())func)();
+ break;
+ case _JC_TYPE_SHORT:
+ asm volatile ("movl %0,%%ecx" : : "m" (words[2]) : "sp", "cx");
+ asm volatile ("movl %0,%%edx" : : "m" (words[1]) : "sp", "dx");
+ asm volatile ("movl %0,%%eax" : : "m" (words[0]) : "sp", "ax");
+ retval->s = (*(jshort (*)())func)();
+ break;
+ case _JC_TYPE_INT:
+ asm volatile ("movl %0,%%ecx" : : "m" (words[2]) : "sp", "cx");
+ asm volatile ("movl %0,%%edx" : : "m" (words[1]) : "sp", "dx");
+ asm volatile ("movl %0,%%eax" : : "m" (words[0]) : "sp", "ax");
+ retval->i = (*(jint (*)())func)();
+ break;
+ case _JC_TYPE_LONG:
+ asm volatile ("movl %0,%%ecx" : : "m" (words[2]) : "sp", "cx");
+ asm volatile ("movl %0,%%edx" : : "m" (words[1]) : "sp", "dx");
+ asm volatile ("movl %0,%%eax" : : "m" (words[0]) : "sp", "ax");
+ retval->j = (*(jlong (*)())func)();
+ break;
+ case _JC_TYPE_FLOAT:
+ asm volatile ("movl %0,%%ecx" : : "m" (words[2]) : "sp", "cx");
+ asm volatile ("movl %0,%%edx" : : "m" (words[1]) : "sp", "dx");
+ asm volatile ("movl %0,%%eax" : : "m" (words[0]) : "sp", "ax");
+ retval->f = (*(jfloat (*)())func)();
+ break;
+ case _JC_TYPE_DOUBLE:
+ asm volatile ("movl %0,%%ecx" : : "m" (words[2]) : "sp", "cx");
+ asm volatile ("movl %0,%%edx" : : "m" (words[1]) : "sp", "dx");
+ asm volatile ("movl %0,%%eax" : : "m" (words[0]) : "sp", "ax");
+ retval->d = (*(jdouble (*)())func)();
+ break;
+ case _JC_TYPE_REFERENCE:
+ asm volatile ("movl %0,%%ecx" : : "m" (words[2]) : "sp", "cx");
+ asm volatile ("movl %0,%%edx" : : "m" (words[1]) : "sp", "dx");
+ asm volatile ("movl %0,%%eax" : : "m" (words[0]) : "sp", "ax");
+ retval->l = (*(_jc_object *(*)())func)();
+ break;
+ case _JC_TYPE_VOID:
+ asm volatile ("movl %0,%%ecx" : : "m" (words[2]) : "sp", "cx");
+ asm volatile ("movl %0,%%edx" : : "m" (words[1]) : "sp", "dx");
+ asm volatile ("movl %0,%%eax" : : "m" (words[0]) : "sp", "ax");
+ (*(void (*)())func)();
+ break;
+ default:
+ _JC_ASSERT(JNI_FALSE);
+ }
+
+ /* Repair stack pointer */
+ for (i = nwords; --i >= 0; ) {
+ if (i >= 3 || push[i])
+ asm volatile ("addl $4,%%esp" : : : "cc", "sp");
+ }
+}
+
+#else /* !_JC_I386_REGPARM */
+
+void
+_jc_dynamic_invoke(const void *func, int jcni, int nparams,
+ const u_char *ptypes, int nwords, _jc_word *words, _jc_value *retval)
+{
+ int i;
+
+ /* Push parameters onto the stack */
+ for (i = nwords; --i >= 0; )
+ asm volatile ("pushl %0" : : "m" (words[i]) : "sp");
+
+ /* Invoke function */
+ switch (ptypes[nparams]) {
+ case _JC_TYPE_BOOLEAN:
+ retval->z = (*(jboolean (*)())func)();
+ break;
+ case _JC_TYPE_BYTE:
+ retval->b = (*(jbyte (*)())func)();
+ break;
+ case _JC_TYPE_CHAR:
+ retval->c = (*(jchar (*)())func)();
+ break;
+ case _JC_TYPE_SHORT:
+ retval->s = (*(jshort (*)())func)();
+ break;
+ case _JC_TYPE_INT:
+ retval->i = (*(jint (*)())func)();
+ break;
+ case _JC_TYPE_LONG:
+ retval->j = (*(jlong (*)())func)();
+ break;
+ case _JC_TYPE_FLOAT:
+ retval->f = (*(jfloat (*)())func)();
+ break;
+ case _JC_TYPE_DOUBLE:
+ retval->d = (*(jdouble (*)())func)();
+ break;
+ case _JC_TYPE_REFERENCE:
+ retval->l = (*(_jc_object *(*)())func)();
+ break;
+ case _JC_TYPE_VOID:
+ (*(void (*)())func)();
+ break;
+ default:
+ _JC_ASSERT(JNI_FALSE);
+ }
+
+ /* Repair stack pointer */
+ asm volatile ("addl %0,%%esp" : : "r" (nwords * 4) : "cc", "sp");
+}
+
+#endif /* !_JC_I386_REGPARM */
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_definitions.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_definitions.h?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_definitions.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_definitions.h Tue Oct 4 19:19:16 2005
@@ -0,0 +1,83 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: i386_definitions.h,v 1.6 2005/05/08 21:12:07 archiecobbs Exp $
+ */
+
+#ifndef _ARCH_I386_DEFINITIONS_H_
+#define _ARCH_I386_DEFINITIONS_H_
+
+#if !defined(__i386__)
+#error "This include file is for the i386 architecture only"
+#endif
+
+#define _JC_PAGE_SHIFT 12 /* 4096 byte pages */
+
+#define _JC_ELF_CLASS ELFCLASS32
+#define _JC_ELF_DATA ELFDATA2LSB
+#define _JC_ELF_MACHINE EM_386
+
+#define _JC_STACK_ALIGN 2
+
+#define _JC_BIG_ENDIAN 0
+
+#ifdef __FreeBSD__
+
+#define _JC_REGISTER_OFFS { \
+ _JC_OFFSETOF(mcontext_t, mc_gs), \
+ _JC_OFFSETOF(mcontext_t, mc_fs), \
+ _JC_OFFSETOF(mcontext_t, mc_es), \
+ _JC_OFFSETOF(mcontext_t, mc_ds), \
+ _JC_OFFSETOF(mcontext_t, mc_edi), \
+ _JC_OFFSETOF(mcontext_t, mc_esi), \
+ _JC_OFFSETOF(mcontext_t, mc_ebp), \
+ _JC_OFFSETOF(mcontext_t, mc_isp), \
+ _JC_OFFSETOF(mcontext_t, mc_ebx), \
+ _JC_OFFSETOF(mcontext_t, mc_edx), \
+ _JC_OFFSETOF(mcontext_t, mc_ecx), \
+ _JC_OFFSETOF(mcontext_t, mc_eax), \
+ _JC_OFFSETOF(mcontext_t, mc_cs), \
+ _JC_OFFSETOF(mcontext_t, mc_esp), \
+ _JC_OFFSETOF(mcontext_t, mc_ss), \
+ }
+
+#elif defined(__linux__)
+
+#define _JC_REGISTER_OFFS { \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_GS * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_FS * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_ES * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_DS * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_EDI * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_ESI * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_EBP * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_ESP * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_EBX * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_EDX * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_ECX * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_EAX * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_CS * sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_UESP* sizeof(greg_t), \
+ _JC_OFFSETOF(mcontext_t, gregs) + REG_SS * sizeof(greg_t), \
+ }
+
+#else
+#error "Unsupported O/S for i386 _JC_REGISTER_OFFS"
+#endif
+
+#endif /* _ARCH_I386_DEFINITIONS_H_ */
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_libjc.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_libjc.h?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_libjc.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_libjc.h Tue Oct 4 19:19:16 2005
@@ -0,0 +1,143 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: i386_libjc.h,v 1.7 2005/05/08 21:12:07 archiecobbs Exp $
+ */
+
+#ifndef _ARCH_I386_LIBJC_H_
+#define _ARCH_I386_LIBJC_H_
+
+/*
+ * Architecture-specific functions for i386 architecture.
+ */
+
+extern inline int
+_jc_compare_and_swap(volatile _jc_word *word, _jc_word old, _jc_word new)
+{
+ _jc_word previous;
+
+ asm __volatile__ (
+ "lock\n"
+ "\tcmpxchgl %1,%2\n"
+ : "=a" (previous)
+ : "q" (new), "m" (*word), "0" (old)
+ : "memory");
+ return previous == old;
+}
+
+extern inline void
+_jc_iflush(const void *mem, size_t len)
+{
+ /* nothing to do: i386 has coherent data and instruction caches */
+}
+
+extern inline void
+_jc_stack_frame_init(_jc_stack_frame *framep)
+{
+ *framep = NULL;
+}
+
+#define _jc_stack_frame_current(framep) \
+ do { \
+ *(framep) = __builtin_frame_address(0); \
+ } while (0)
+
+extern inline void
+_jc_stack_frame_next(_jc_stack_frame *framep, const void **pcp)
+{
+ _jc_word *const ebp = *framep;
+
+ *pcp = (const void *)ebp[1]; /* saved %eip is one slot above %ebp */
+ *framep = (_jc_word *)ebp[0]; /* %ebp points to saved %ebp */
+}
+
+extern inline jboolean
+_jc_stack_frame_valid(_jc_stack_frame frame)
+{
+ return frame != NULL;
+}
+
+extern inline jboolean
+_jc_stack_frame_equal(_jc_stack_frame frame1, _jc_stack_frame frame2)
+{
+ return frame1 == frame2;
+}
+
+extern inline const void *
+_jc_stack_frame_sp(_jc_stack_frame frame)
+{
+ return (const void *)frame;
+}
+
+#ifdef __FreeBSD__
+
+extern inline const void *
+_jc_mcontext_sp(const mcontext_t *mctx)
+{
+ return (const void *)mctx->mc_esp;
+}
+
+extern inline const void *
+_jc_mcontext_pc(const mcontext_t *mctx)
+{
+ return (const void *)mctx->mc_eip;
+}
+
+extern inline _jc_stack_frame
+_jc_mcontext_frame(const mcontext_t *mctx)
+{
+ return (_jc_word *)mctx->mc_ebp;
+}
+
+extern inline const void *
+_jc_signal_fault_address(int sig_num, siginfo_t *info, ucontext_t *uctx)
+{
+ return (const void *)uctx->uc_mcontext.mc_err;
+}
+
+#elif defined(__linux__)
+
+extern inline const void *
+_jc_mcontext_sp(const mcontext_t *mctx)
+{
+ return (const void *)mctx->gregs[REG_ESP];
+}
+
+extern inline const void *
+_jc_mcontext_pc(const mcontext_t *mctx)
+{
+ return (const void *)mctx->gregs[REG_EIP];
+}
+
+extern inline _jc_stack_frame
+_jc_mcontext_frame(const mcontext_t *mctx)
+{
+ return (_jc_word *)mctx->gregs[REG_EBP];
+}
+
+extern inline const void *
+_jc_signal_fault_address(int sig_num, siginfo_t *info, ucontext_t *uctx)
+{
+ return (const void *)info->si_addr;
+}
+
+#else
+#error "Unsupported O/S for i386 machine context functions"
+#endif
+
+#endif /* _ARCH_I386_LIBJC_H_ */
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_structures.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_structures.h?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_structures.h (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/arch/i386/i386_structures.h Tue Oct 4 19:19:16 2005
@@ -0,0 +1,47 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: i386_structures.h,v 1.1.1.1 2004/02/20 05:15:49 archiecobbs Exp $
+ */
+
+#ifndef _ARCH_I386_STRUCTURES_H_
+#define _ARCH_I386_STRUCTURES_H_
+
+/*
+ * i386 stack frame:
+ *
+ * | ... |
+ * +-------------+
+ * | param2 |
+ * +-------------+
+ * | param1 |
+ * +-------------+
+ * | param0 |
+ * +-------------+
+ * | return addr |
+ * +-------------+
+ * | saved %epb | <== %ebp
+ * +-------------+
+ * | locals... |
+ *
+ * So all we need is a pointer to the saved %epb register.
+ */
+
+typedef _jc_word *_jc_stack_frame; /* pointer to saved %epb */
+
+#endif /* _ARCH_I386_STRUCTURES_H_ */
+
Added: incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/array.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/array.c?rev=294974&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/array.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/jchevm/jchevm/libjc/array.c Tue Oct 4 19:19:16 2005
@@ -0,0 +1,135 @@
+
+/*
+ * Copyright 2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Id: array.c,v 1.6 2005/03/13 00:18:51 archiecobbs Exp $
+ */
+
+#include "libjc.h"
+
+/* Internal functions */
+static jint _jc_gen_array_hash_tables(_jc_env *env);
+
+/*
+ * Do one-time initialization for array types.
+ *
+ * If unsuccessful an exception is stored.
+ */
+jint
+_jc_setup_array_types(_jc_env *env)
+{
+ jint status;
+
+ /* Sanity check */
+ _JC_ASSERT(env->vm->initialization != NULL);
+
+ /* Generate array type's hash and "quick" lookup tables */
+ if ((status = _jc_gen_array_hash_tables(env)) != JNI_OK)
+ return status;
+
+ /* Done */
+ return JNI_OK;
+}
+
+/*
+ * Generate interface list and hash tables for array types.
+ *
+ * If unsuccessful an exception is stored.
+ */
+static jint
+_jc_gen_array_hash_tables(_jc_env *env)
+{
+ _jc_jvm *const vm = env->vm;
+ _jc_boot_array *const array = &vm->boot.array;
+ _jc_type *const interfaces[] = { /* arrays implement these */
+ vm->boot.types.Cloneable,
+ vm->boot.types.Serializable,
+ };
+ const int num_interfaces = sizeof(interfaces) / sizeof(*interfaces);
+ _jc_method *clone;
+ int bucket;
+
+ /* Sanity check */
+ _JC_ASSERT(array->interfaces == NULL);
+ _JC_ASSERT(array->imethod_hash_table == NULL);
+ _JC_ASSERT(array->imethod_quick_table == NULL);
+
+ /* Lock boot loader */
+ _JC_MUTEX_LOCK(env, vm->boot.loader->mutex);
+
+ /* Allocate interface list */
+ if ((array->interfaces = _jc_cl_zalloc(env, vm->boot.loader,
+ num_interfaces * sizeof(*array->interfaces))) == NULL)
+ goto fail;
+
+ /* Fill in interface list */
+ array->num_interfaces = num_interfaces;
+ memcpy(array->interfaces, interfaces,
+ num_interfaces * sizeof(*interfaces));
+
+ /* Allocate hash table and quick lookup table */
+ if ((array->imethod_hash_table = _jc_cl_zalloc(env, vm->boot.loader,
+ _JC_IMETHOD_HASHSIZE * sizeof(*array->imethod_hash_table))) == NULL)
+ goto fail;
+ if ((array->imethod_quick_table = _jc_cl_zalloc(env, vm->boot.loader,
+ _JC_IMETHOD_HASHSIZE * sizeof(*array->imethod_quick_table)))
+ == NULL)
+ goto fail;
+
+ /* Find Object.clone() method */
+ if ((clone = _jc_get_declared_method(env, vm->boot.types.Object,
+ "clone", "()Ljava/lang/Object;", _JC_ACC_STATIC, 0)) == NULL)
+ goto fail;
+
+ /* Get hash table index for clone() */
+ bucket = clone->signature_hash & (_JC_IMETHOD_HASHSIZE - 1);
+
+ /* Create hash table bucket */
+ if ((array->imethod_hash_table[bucket] = _jc_cl_zalloc(env,
+ vm->boot.loader, 2 * sizeof(*array->imethod_hash_table[bucket])))
+ == NULL)
+ goto fail;
+
+ /* Put clone() in the bucket */
+ array->imethod_hash_table[bucket][0] = clone;
+ array->imethod_hash_table[bucket][1] = NULL;
+
+ /*
+ * Put clone() in the "quick" method lookup table. It's the only
+ * interface method implemented by arrays so we trivially know
+ * there are no other methods in the same hash bucket.
+ */
+ array->imethod_quick_table[bucket] = clone->function;
+
+ /* Unlock boot loader */
+ _JC_MUTEX_UNLOCK(env, vm->boot.loader->mutex);
+
+ /* Done */
+ return JNI_OK;
+
+fail:
+ /* Clean up after failure */
+ _jc_cl_unalloc(vm->boot.loader, &array->imethod_quick_table,
+ _JC_IMETHOD_HASHSIZE * sizeof(*array->imethod_quick_table));
+ _jc_cl_unalloc(vm->boot.loader, &array->imethod_hash_table,
+ _JC_IMETHOD_HASHSIZE * sizeof(*array->imethod_hash_table));
+ _jc_cl_unalloc(vm->boot.loader, &array->interfaces,
+ num_interfaces * sizeof(*array->interfaces));
+ _JC_MUTEX_UNLOCK(env, vm->boot.loader->mutex);
+ return JNI_ERR;
+}
+
+