[kaffe] CVS kaffe (guilhem): Loads of fixes (especially concerning
weak references).
Kaffe CVS
cvs-commits at kaffe.org
Tue Apr 12 11:48:29 PDT 2005
PatchSet 5674
Date: 2005/04/12 18:43:15
Author: guilhem
Branch: HEAD
Tag: (none)
Log:
Loads of fixes (especially concerning weak references).
* kaffe/kaffe/version.c
(printShortVersion): Print the default heap sizes and stack size.
* kaffe/kaffevm/classMethod.h
(Hjava_lang_Class): Removed unused finalizer_call.
* kaffe/kaffevm/gcFuncs.c
(initCollector): Strings/arrays must be finalized in case a weak
reference is attached to the object.
* kaffe/kaffevm/reference.c
(KaffeVM_isReferenced): Fixed though the function is currently
unused.
(referenceObjectFinalizer, referenceFinalizer): Added DBG
instructions.
* kaffe/kaffevm/thread.c, kaffe/kaffevm/thread.h
(attachFakedThreadInstance): Renamed into...
(KaffeVM_attachFakedThreadInstance): Renamed from
attachFakedThreadInstance.
(KaffeVM_detachCurrenThread): New dummy function.
* kaffe/kaffevm/utf8const.c: Removed a few 'if !defined(KAFFEH)'.
* kaffe/kaffevm/jni/jni.c
(KaffeJNI_AttachThread, KaffeJNI_AttachThreadAsDaemon): Use
KaffeVM_* function now.
* kaffe/kaffevm/kaffe-gc/gc-incremental.c
(finishGC): Clarified a comment.
(finaliserJob): Do not clear the stack anymore. Removed iLockRoot
renamed. Invoke KaffeGC_clearWeakRef before finalizing.
* kaffe/kaffevm/kaffe-gc/gc-refs.h
(weakRefObject): Added new fields to keep track precisely of the
allocation state of the object.
* kaffe/kaffevm/kaffe-gc/gc-refs.c
(resizeWeakReferenceObject): New auxiliary function.
(KaffeGC_rmWeakRef): Check whether the object has been removed during GC calls.
Do not resize dynamically the reference array.
(KaffeGC_addWeakRef): Use resizeWeakReferenceObject.
(KaffeGC_clearWeakRefs): Be gentle when destroying the weak
reference object.
* libraries/javalib/java/lang/ref/Reference.java
(clear): Do not clear referent but clear queue according to Java API.
Members:
ChangeLog:1.3840->1.3841
kaffe/kaffe/version.c:INITIAL->1.10
kaffe/kaffevm/classMethod.h:INITIAL->1.80
kaffe/kaffevm/gcFuncs.c:INITIAL->1.70
kaffe/kaffevm/reference.c:1.5->1.6
kaffe/kaffevm/thread.c:INITIAL->1.96
kaffe/kaffevm/thread.h:INITIAL->1.27
kaffe/kaffevm/utf8const.c:INITIAL->1.48
kaffe/kaffevm/jni/jni.c:1.22->1.23
kaffe/kaffevm/kaffe-gc/gc-incremental.c:1.22->1.23
kaffe/kaffevm/kaffe-gc/gc-refs.c:1.13->1.14
libraries/javalib/java/lang/ref/Reference.java:INITIAL->1.6
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3840 kaffe/ChangeLog:1.3841
--- kaffe/ChangeLog:1.3840 Tue Apr 12 14:57:16 2005
+++ kaffe/ChangeLog Tue Apr 12 18:43:15 2005
@@ -1,4 +1,54 @@
-2005-04-11 Guilhem Lavaux <guilhem at kaffe.org>
+2005-04-12 Guilhem Lavaux <guilhem at kaffe.org>
+
+ * kaffe/kaffe/version.c
+ (printShortVersion): Print the default heap sizes and stack size.
+
+ * kaffe/kaffevm/classMethod.h
+ (Hjava_lang_Class): Removed unused finalizer_call.
+
+ * kaffe/kaffevm/gcFuncs.c
+ (initCollector): Strings/arrays must be finalized in case a weak
+ reference is attached to the object.
+
+ * kaffe/kaffevm/reference.c
+ (KaffeVM_isReferenced): Fixed though the function is currently
+ unused.
+ (referenceObjectFinalizer, referenceFinalizer): Added DBG
+ instructions.
+
+ * kaffe/kaffevm/thread.c, kaffe/kaffevm/thread.h
+ (attachFakedThreadInstance): Renamed into...
+ (KaffeVM_attachFakedThreadInstance): Renamed from
+ attachFakedThreadInstance.
+ (KaffeVM_detachCurrenThread): New dummy function.
+
+ * kaffe/kaffevm/utf8const.c: Removed a few 'if !defined(KAFFEH)'.
+
+ * kaffe/kaffevm/jni/jni.c
+ (KaffeJNI_AttachThread, KaffeJNI_AttachThreadAsDaemon): Use
+ KaffeVM_* function now.
+
+ * kaffe/kaffevm/kaffe-gc/gc-incremental.c
+ (finishGC): Clarified a comment.
+ (finaliserJob): Do not clear the stack anymore. Removed iLockRoot
+ renamed. Invoke KaffeGC_clearWeakRef before finalizing.
+
+ * kaffe/kaffevm/kaffe-gc/gc-refs.h
+ (weakRefObject): Added new fields to keep track precisely of the
+ allocation state of the object.
+
+ * kaffe/kaffevm/kaffe-gc/gc-refs.c
+ (resizeWeakReferenceObject): New auxiliary function.
+ (KaffeGC_rmWeakRef): Check whether the object has been removed during GC calls.
+ Do not resize dynamically the reference array.
+ (KaffeGC_addWeakRef): Use resizeWeakReferenceObject.
+ (KaffeGC_clearWeakRefs): Be gentle when destroying the weak
+ reference object.
+
+ * libraries/javalib/java/lang/ref/Reference.java
+ (clear): Do not clear referent but clear queue according to Java API.
+
+2005-04-12 Guilhem Lavaux <guilhem at kaffe.org>
Nektarios K. Papadopoulos <npapadop at inaccessnetworks.com>
* kaffe/kaffevm/systems/unix-pthreads/syscalls.c
===================================================================
Checking out kaffe/kaffe/kaffe/version.c
RCS: /home/cvs/kaffe/kaffe/kaffe/kaffe/version.c,v
VERS: 1.10
***************
--- /dev/null Sun Aug 4 19:57:58 2002
+++ kaffe/kaffe/kaffe/version.c Tue Apr 12 18:48:28 2005
@@ -0,0 +1,66 @@
+/*
+ * version.c
+ *
+ * Copyright (c) 2000 The University of Utah. All rights Reserved.
+ *
+ * This file is distributed as is under the terms of the GNU General
+ * Public License.
+ */
+
+/* Print out the Kaffe version information.
+ * This is in a separate file because the version-info.h header file is
+ * re-generated for each compile, and this minimizes the dependencies.
+ */
+#include "config.h"
+#include "config-std.h"
+#include "version.h"
+#include "version-info.h" /* generated at compile time */
+#include "gc.h"
+#include "md.h"
+
+extern char* engine_name; /* defined in the engine's library */
+
+/* Must not be initialized in place, because stderr is not always a
+ * compile-time constant. */
+static FILE* versionfd /* = stderr */;
+
+void
+printShortVersion(void)
+{
+ if (!versionfd)
+ versionfd = stderr;
+ fprintf(versionfd, "%s\n\n", PACKAGE_NAME);
+ fprintf(versionfd, "Copyright (c) 1996-2004 Kaffe.org project contributors (please see\n");
+ fprintf(versionfd, " the source code for a full list of contributors). All rights reserved.\n");
+ fprintf(versionfd, "Portions Copyright (c) 1996-2002 Transvirtual Technologies, Inc.\n\n");
+
+ fprintf(versionfd, "The Kaffe virtual machine is free software, licensed under the terms of\n");
+ fprintf(versionfd, "the GNU General Public License. Kaffe.org is a an independent, free software\n");
+ fprintf(versionfd, "community project, not directly affiliated with Transvirtual Technologies,\n");
+ fprintf(versionfd, "Inc. Kaffe is a Trademark of Transvirtual Technologies, Inc. Kaffe comes\n");
+ fprintf(versionfd, "with ABSOLUTELY NO WARRANTY.\n\n");
+
+ fprintf(versionfd, "Engine: %s Version: %s Java Version: %s\n",
+ engine_name, PACKAGE_VERSION, JAVA_VERSION_STRING);
+ fprintf(versionfd, "Heap defaults: minimum size: %d MB, maximum size: %d MB\n",
+ MIN_HEAPSIZE / (1024*1024), MAX_HEAPSIZE / (1024*1024));
+ fprintf(versionfd, "Stack default size: %d KB\n", THREADSTACKSIZE / 1024);
+}
+
+void
+printFullVersion(void)
+{
+ printShortVersion();
+ fprintf(versionfd, "Configuration/Compilation options:\n");
+ fprintf(versionfd, " Compile date : %s\n", VER_COMPILE_DATE);
+ fprintf(versionfd, " Compile host : %s\n", VER_COMPILE_HOST);
+ fprintf(versionfd, " Install prefix : %s\n", VER_PREFIX);
+ fprintf(versionfd, " Thread system : %s\n", VER_THREAD_SYSTEM);
+ fprintf(versionfd, " Garbage Collector: %s\n", VER_GARBAGE_COLLECTOR);
+ fprintf(versionfd, " CC : %s\n", VER_CC);
+ fprintf(versionfd, " CFLAGS : %s\n", VER_CFLAGS);
+ fprintf(versionfd, " LDFLAGS : %s\n", VER_LDFLAGS);
+ fprintf(versionfd, " ChangeLog head : %s\n", VER_CHANGELOG_HEAD);
+ /* fprintf(versionfd, " Libraries : %s\n", VER_KAFFELIBS); */
+}
+
===================================================================
Checking out kaffe/kaffe/kaffevm/classMethod.h
RCS: /home/cvs/kaffe/kaffe/kaffe/kaffevm/classMethod.h,v
VERS: 1.80
***************
--- /dev/null Sun Aug 4 19:57:58 2002
+++ kaffe/kaffe/kaffevm/classMethod.h Tue Apr 12 18:48:28 2005
@@ -0,0 +1,632 @@
+/*
+ * classMethod.h
+ * Class, method and field tables.
+ *
+ * Copyright (c) 1996, 1997, 2004
+ * Transvirtual Technologies, Inc. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+
+#ifndef __classmethod_h
+#define __classmethod_h
+
+#include "gtypes.h"
+#include "access.h"
+#include "object.h"
+#include "md.h" /* XXX: need this here so KAFFE_PROFILER is accurately def'd */
+#include "constants.h"
+#include "errors.h"
+#include "jthread.h"
+#include "locks.h"
+
+#define MAXMETHOD 64
+
+/* Class state */
+typedef enum {
+ CSTATE_FAILED = -1,
+ CSTATE_UNLOADED,
+ CSTATE_LOADED,
+ CSTATE_LOADED_SUPER,
+ CSTATE_PRELOADED,
+ CSTATE_VERIFIED,
+ CSTATE_DOING_PREPARE,
+ CSTATE_PREPARED,
+ CSTATE_DOING_LINK,
+ CSTATE_LINKED,
+ CSTATE_CONSTINIT,
+ CSTATE_DOING_SUPER,
+ CSTATE_USABLE,
+ CSTATE_DOING_INIT,
+ CSTATE_COMPLETE
+} class_state_t;
+
+struct _classEntry;
+struct _innerClass;
+struct Hjava_lang_String;
+struct _jitCodeHeader;
+
+#include <java_lang_ClassLoader.h>
+#include "reference.h"
+
+/**
+ * Builtin stab type IDs.
+ */
+typedef enum {
+ STYPE_INT = 1,
+ STYPE_INT_POINTER,
+ STYPE_BYTE,
+ STYPE_BYTE_POINTER,
+ STYPE_SHORT,
+ STYPE_SHORT_POINTER,
+ STYPE_CHAR,
+ STYPE_CHAR_POINTER,
+ STYPE_LONG,
+ STYPE_LONG_POINTER,
+ STYPE_FLOAT,
+ STYPE_FLOAT_POINTER,
+ STYPE_DOUBLE,
+ STYPE_DOUBLE_POINTER,
+ STYPE_BOOLEAN,
+ STYPE_BOOLEAN_POINTER,
+ STYPE_VOID,
+ STYPE_VOID_POINTER,
+ STYPE_DISPATCH_TABLE,
+ STYPE_ILOCK,
+ STYPE_PROMOTED_BYTE,
+ STYPE_PROMOTED_SHORT,
+ STYPE_PROMOTED_CHAR,
+ STYPE_PROMOTED_BOOLEAN,
+ STYPE_MAX
+} stype_t;
+
+struct Hjava_lang_Class {
+ Hjava_lang_Object head; /* A class is an object too */
+
+ struct _iLock* lock; /* Lock for internal use */
+
+ /* Link to class entry */
+ struct _classEntry* centry;
+
+ Utf8Const* name;
+ unsigned int packageLength;
+ char* sourcefile; /* source file name if known */
+ accessFlags accflags;
+
+ /* If non-NULL, a pointer to the superclass.
+ * However, if state < CSTATE_DOING_PREPARE, then
+ * (int) superclass is a constant pool index. */
+ struct Hjava_lang_Class* superclass;
+
+ struct _constants constants;
+
+ /* For regular classes, an array of the methods defined in this class.
+ For array types, used for CLASS_ELEMENT_TYPE.
+ For primitive types, used by CLASS_ARRAY_CACHE. */
+ Method* methods;
+ short method_count;
+
+ /* Number of methods in the dtable. */
+ /* If CLASS_IS_PRIMITIVE, then the CLASS_PRIM_SIG. */
+ short msize;
+
+ /* Pointer to array of Fields, on for each field.
+ Static fields come first. */
+ Field* fields;
+
+ /* The size of the non-static fields, in bytes.
+ For a primitive type, the length in bytes.
+ Also used temporarily while reading fields. */
+ int size_in_bytes;
+
+ /* Number of fields, including static fields. */
+ short field_count;
+ /* Number of static fields. */
+ short nsfields;
+
+ struct _dispatchTable* vtable;
+
+ /* all interfaces supported by this class */
+ struct Hjava_lang_Class** interfaces;
+ short* if2itable; /* redundant now */
+ void** itable2dtable;
+ short interface_len;
+ short total_interface_len;
+ /* pointers to all itable2dtable entries of classes implementing this interface */
+ void*** implementors; /* interfaces only */
+ int impl_index; /* index of the class in the implementors array. */
+
+ Hjava_lang_ClassLoader* loader;
+
+ /* A bitmap describing the layout of instances of that class.
+ It contains CLASS_FSIZE/ALIGNMENTVOIDP bits.
+ The MSB corresponds to the dtable field.
+ */
+ int* gc_layout;
+ class_state_t state;
+ void* processingThread;
+ /* This pointer contains the method which should be called
+ * at object finalization.
+ */
+ Method* finalizer;
+ int alloc_type; /* allocation type */
+
+ /* array containing static data */
+ void* static_data;
+
+ /* InnerClasses attribute */
+ short this_index;
+ short this_inner_index;
+ short nr_inner_classes;
+ struct _innerClass* inner_classes;
+
+ /* misc other stuff */
+ void* gcjPeer; /* only needed if GCJ_SUPPORT */
+#ifdef KAFFE_VMDEBUG
+ int live_count;
+#endif
+#if defined(KAFFE_XPROFILER) || defined(KAFFE_XDEBUGGING)
+ /** Stab type ID. */
+ int stab_id;
+#endif
+
+ /** The array of 'signer' objects; usually Certificates. */
+ HArrayOfObject* signers;
+
+ /** The protection domain */
+ struct Hjava_security_ProtectionDomain* protectionDomain;
+};
+
+#ifndef __DEFINED_CLASS
+#define __DEFINED_CLASS
+typedef struct Hjava_lang_Class Hjava_lang_Class;
+#endif
+
+/*
+ * Functions for locking and waiting on *internal* class
+ * bits. This is not for static+synchronized methods.
+ * Use the centry lock, as it is convenient and available.
+ */
+#define lockClass(C) lockMutex(((C)))
+#define unlockClass(C) unlockMutex(((C)))
+#define waitOnClass(C) waitCond(((C)), 0)
+#define signalOnClass(C) signalCond(((C)))
+#define broadcastOnClass(C) broadcastCond(((C)))
+
+#define METHOD_TRANSLATED(M) ((M)->accflags & ACC_TRANSLATED)
+#define METHOD_JITTED(M) ((M)->accflags & ACC_JITTED)
+
+#define METHOD_NATIVECODE(M) (((M)->idx == -1) ? \
+ ((M)->ncode) : \
+ ((M)->class->vtable->method[(M)->idx]))
+
+/* Like METHOD_NATIVECODE, except we take the address ---
+ * gcc doesn't compile &( ? : ) expressions for some reason
+ */
+#define PMETHOD_NATIVECODE(M) (((M)->idx == -1) ? \
+ (void*)&((M)->ncode) : \
+ &((M)->class->vtable->method[(M)->idx]))
+
+/**
+ * Get start of native code of a method
+ *
+ * @param method a method
+ * @return pointer to start of code
+ */
+struct _jitCodeHeader* getMethodCodeStart(Method * method);
+
+/**
+ * Set start of native code of a method
+ *
+ * @param method a method
+ * @param start pointer to start of code
+ */
+void setMethodCodeStart(Method * method, struct _jitCodeHeader* start);
+
+#define _SET_METHOD_NATIVECODE(M, C) do {\
+ if ((M)->idx == -1) {\
+ (M)->ncode = (C);\
+ } else { \
+ (M)->class->vtable->method[(M)->idx] = (C);\
+ } \
+} while (0)
+#define SET_METHOD_NATIVECODE(M, C) _SET_METHOD_NATIVECODE(M, C); \
+ (M)->accflags |= ACC_TRANSLATED
+#define SET_METHOD_JITCODE(M, C) _SET_METHOD_NATIVECODE(M, C); \
+ (M)->accflags |= ACC_TRANSLATED|ACC_JITTED
+
+/*
+ * Stats for the nameMapping object.
+ *
+ * searching - The system is searching for this particular class.
+ * loading - The system is loading this particular class and/or its parents.
+ * If a circularity exists in the hierarchy it will be detected in this
+ * state.
+ * loaded - The class and its parents have been loaded.
+ * done - The class have been loaded and verified.
+ */
+typedef enum {
+ NMS_EMPTY,
+ NMS_SEARCHING,
+ NMS_LOADING,
+ NMS_LOADED,
+ NMS_DONE
+} name_mapping_state_t;
+
+/*
+ * Class hash entry.
+ */
+typedef struct _classEntry {
+ struct _classEntry* next;
+ Utf8Const* name;
+
+ iStaticLock slock;
+ name_mapping_state_t state;
+ Hjava_lang_ClassLoader* loader;
+ union {
+ jthread_t thread;
+ struct Hjava_lang_Class *cl;
+ } data;
+} classEntry;
+
+/*
+ * The nameDependency structure is used to detect cycles between classes.
+ * Basically, its used as a simple deadlock detection system.
+ *
+ * next - The next object in the list.
+ * thread - The thread that is blocked on "mapping".
+ * mapping - The mapping that "thread" is waiting for.
+ */
+typedef struct _nameDependency {
+ struct _nameDependency *next;
+ jthread_t thread;
+ classEntry *mapping;
+} nameDependency;
+
+typedef struct _innerClass {
+ u2 outer_class;
+ u2 inner_class;
+ u2 inner_class_accflags;
+} innerClass;
+
+typedef struct _parsed_signature {
+ Utf8Const* signature;
+ u2 nargs;
+ u2 ret_and_args[1]; /* index into signature */
+ /* ret_and_args[0]: return value
+ ret_and_args[1]: first argument
+ etc */
+} parsed_signature_t;
+
+typedef struct _methods {
+ Utf8Const* name;
+ parsed_signature_t* parsed_sig;
+ accessFlags accflags;
+ long idx; /* Index into class->vtable */
+ u2 stacksz;
+ u2 localsz;
+ /* Only used for static/final/constructor methods */
+ nativecode* ncode;
+ union {
+ struct {
+ struct _jitCodeHeader* ncode_start;
+ nativecode* ncode_end;
+ } ncode;
+ struct {
+ unsigned char* code;
+ int codelen;
+ } bcode;
+ } c;
+ Hjava_lang_Class* class;
+ struct _lineNumbers* lines;
+ struct _localVariables* lvars;
+ struct _jexception* exception_table;
+ int ndeclared_exceptions;
+ union {
+ constIndex* local_exceptions;
+ struct _methods* remote_exceptions;
+ } declared_exceptions_u;
+#define declared_exceptions declared_exceptions_u.local_exceptions
+ int framesize; /* JIT only: size of frame */
+
+#if defined(KAFFE_PROFILER)
+ profiler_click_t jitClicks;
+ profiler_click_t totalClicks;
+ profiler_click_t totalChildrenClicks;
+ int callsCount;
+#endif
+} methods;
+
+#define METHOD_NAME(M) ((M)->name)
+#define METHOD_NAMED(M) (METHOD_NAME(M)->data)
+
+#define PSIG_UTF8(sig) ((sig)->signature)
+#define PSIG_DATA(sig) (PSIG_UTF8((sig))->data)
+#define PSIG_RET(sig) ((sig)->ret_and_args[0])
+#define PSIG_NARGS(sig) (sig->nargs)
+#define PSIG_ARG(sig,n) ((sig)->ret_and_args[1+n])
+
+#define METHOD_PSIG(M) ((M)->parsed_sig)
+#define METHOD_SIG(M) (PSIG_UTF8(METHOD_PSIG((M))))
+#define METHOD_SIGD(M) (PSIG_DATA(METHOD_PSIG((M))))
+#define METHOD_RET_TYPE(M) (METHOD_SIGD((M))+PSIG_RET(METHOD_PSIG((M))))
+#define METHOD_NARGS(M) (PSIG_NARGS(METHOD_PSIG((M))))
+#define METHOD_ARG_TYPE(M,N) (METHOD_SIGD((M))+PSIG_ARG(METHOD_PSIG((M)),(N)))
+
+#define METHOD_BYTECODE_LEN(M) ((M)->c.bcode.codelen)
+#define METHOD_BYTECODE_CODE(M) ((M)->c.bcode.code)
+
+typedef struct _dispatchTable {
+ Hjava_lang_Class* class;
+ void* __dummy0; /* For GCJ/C++ compatibility. */
+ void* method[1];
+} dispatchTable;
+
+#define DTABLE_CLASS 0
+#define DTABLE_METHODOFFSET (sizeof(void*)*2)
+#define DTABLE_METHODSIZE (sizeof(void*))
+
+typedef struct _fields {
+ Hjava_lang_Class* clazz;
+ Utf8Const* name;
+ Utf8Const* signature;
+ Hjava_lang_Class* type;
+ accessFlags accflags;
+ u2 bsize; /* in bytes */
+ union {
+ int boffset; /* offset in bytes (object) */
+ void* addr; /* address (static) */
+ u2 idx; /* constant value index */
+ } info;
+} fields;
+
+#define FIELD_UNRESOLVED_FLAG 0x8000
+#define FIELD_CONSTANT_VALUE 0x4000
+
+#define FIELD_RESOLVED(FLD) ((FLD)->type != 0 && !((FLD)->accflags & FIELD_UNRESOLVED_FLAG))
+
+/* Type of field FLD. Only valid if FIELD_RESOLVED(FLD). */
+#define FIELD_TYPE(FLD) ((FLD)->type)
+/* Size of field FLD, in bytes. */
+#define FIELD_SIZE(FLD) ((FLD)->bsize)
+#define FIELD_WSIZE(FLD) ((FLD)->bsize <= sizeof(jint) ? 1 : 2)
+#define FIELD_BOFFSET(FLD) ((FLD)->info.boffset)
+#define FIELD_ADDRESS(FLD) ((FLD)->info.addr)
+#define FIELD_CONSTIDX(FLD) ((FLD)->info.idx)
+#define FIELD_ISPRIM(FLD) (FIELD_RESOLVED(FLD) \
+ && CLASS_IS_PRIMITIVE(FIELD_TYPE(FLD)))
+#define FIELD_ISREF(FLD) (!FIELD_ISPRIM(FLD) \
+ && FIELD_TYPE(FLD) != PtrClass)
+#define FIELD_NAME(FLD) ((FLD)->name->data)
+
+#define CLASSMAXSIG 256
+
+struct _Code;
+struct _method_info;
+struct _field_info;
+struct classFile;
+
+#define CLASS_METHODS(CLASS) ((CLASS)->methods)
+#define CLASS_NMETHODS(CLASS) ((CLASS)->method_count)
+
+/* An array containing all the Fields, static fields first. */
+#define CLASS_FIELDS(CLASS) ((CLASS)->fields)
+
+/* An array containing all the static Fields. */
+#define CLASS_SFIELDS(CLASS) ((CLASS)->fields)
+
+/* The static data of this class */
+#define CLASS_STATICDATA(CLASS) ((CLASS)->static_data)
+
+/* An array containing all the instance (non-static) Fields. */
+#define CLASS_IFIELDS(CL) (&(CL)->fields[CLASS_NSFIELDS(CL)])
+
+/* Total number of fields (instance and static). */
+#define CLASS_NFIELDS(CLASS) ((CLASS)->field_count)
+/* Number of instance (non-static) fields. */
+#define CLASS_NIFIELDS(CLASS) ((CLASS)->field_count - (CLASS)->nsfields)
+/* Number of static fields. */
+#define CLASS_NSFIELDS(CLASS) ((CLASS)->nsfields)
+
+/* Size of a class fields (including header), in words. */
+#define CLASS_WFSIZE(CLASS) ((CLASS)->size_in_bytes / sizeof(jint))
+
+/* Size of a class's fields (including header), in bytes. */
+#define CLASS_FSIZE(CLASS) ((CLASS)->size_in_bytes)
+
+#define OBJECT_CLASS(OBJ) ((OBJ)->vtable->class)
+#define CLASS_CNAME(CL) ((CL)->name->data)
+#define CLASS_SOURCEFILE(CL) \
+ ((CL)->sourcefile == 0 ? "source file unknown" : (CL)->sourcefile)
+#define _PRIMITIVE_DTABLE ((struct _dispatchTable*)(-1))
+#define CLASS_IS_PRIMITIVE(CL) ((CL)->vtable == _PRIMITIVE_DTABLE)
+
+/* Assuming CLASS_IS_PRIMITIVE(CL), return the 1-letter signature code. */
+#define CLASS_PRIM_SIG(CL) ((CL)->msize)
+#define CLASS_PRIM_NAME(CL) (*(Utf8Const**)&(CL)->fields)
+
+/* A freshly born class that does have its name set, but the collector
+ * may already want to know whether it'll be a boy or a girl.
+ */
+#define CLASS_IS_ARRAY(CL) ((CL)->name && CLASS_CNAME(CL)[0] == '[')
+
+#define CLASS_IS_INTERFACE(CL) ((CL)->accflags & ACC_INTERFACE)
+#define CLASS_IS_ABSTRACT(CL) ((CL)->accflags & ACC_ABSTRACT)
+#define CLASS_IS_FINAL(CL) ((CL)->accflags & ACC_FINAL)
+
+/* For an array type, the types of the elements. */
+#define CLASS_ELEMENT_TYPE(ARRAYCLASS) (*(Hjava_lang_Class**)&(ARRAYCLASS)->methods)
+
+/* Used by the lookupArray function. */
+#define CLASS_ARRAY_CACHE(PRIMTYPE) (*(Hjava_lang_Class**)&(PRIMTYPE)->methods)
+
+#define TYPE_PRIM_SIZE(CL) ((CL)->size_in_bytes)
+#define TYPE_SIZE(CL) \
+ (CLASS_IS_PRIMITIVE(CL) ? TYPE_PRIM_SIZE (CL) : PTR_TYPE_SIZE)
+
+
+#define METHOD_IS_PUBLIC(METH) ((METH)->accflags & ACC_PUBLIC)
+#define METHOD_IS_PROTECTED(METH) ((METH)->accflags & ACC_PROTECTED)
+#define METHOD_IS_PRIVATE(METH) ((METH)->accflags & ACC_PRIVATE)
+
+#define METHOD_IS_CONSTRUCTOR(METH) ((METH)->accflags & ACC_CONSTRUCTOR)
+#define METHOD_IS_STATIC(METH) ((METH)->accflags & ACC_STATIC)
+
+#define METHOD_IS_ABSTRACT(METH) ((METH)->accflags & ACC_ABSTRACT)
+#define METHOD_IS_FINAL(METH) ((METH)->accflags & ACC_FINAL)
+
+#define METHOD_IS_NATIVE(METH) ((METH)->accflags & ACC_NATIVE)
+#define METHOD_IS_STRICT(METH) ((METH)->accflags & ACC_STRICT)
+#define METHOD_IS_SYNCHRONISED(METH) ((METH)->accflags & ACC_SYNCHRONISED)
+
+
+#define CLASS_GCJ(C) ((C)->accflags & ACC_GCJ)
+#define SET_CLASS_GCJ(C) (C)->accflags |= ACC_GCJ
+
+/* For manipulating the constant pool in a class */
+#define CLASS_CONSTANTS(CL) (&(CL)->constants)
+#define CLASS_CONST_SIZE(CL) ((CL)->constants.size)
+#define CLASS_CONST_TAG(CL, IDX) ((CL)->constants.tags[IDX])
+#define CLASS_CONST_DATA(CL, IDX) ((CL)->constants.data[IDX])
+#define CLASS_CONST_UTF8(CL, IDX) WORD2UTF(CLASS_CONST_DATA(CL, IDX))
+#define CLASS_CONST_INT(CL, IDX) ((int32) CLASS_CONST_DATA(CL, IDX))
+#if SIZEOF_VOID_P == 8
+#define CLASS_CONST_LONG(CL, IDX) \
+ ((uint64) CLASS_CONST_DATA(CL, IDX))
+#else
+#define CLASS_CONST_LONG(CL, IDX) \
+ WORDS_TO_LONG ((CL)->constants.data[IDX], (CL)->constants.data[(IDX)+1])
+#endif
+#define CLASS_CONST_DOUBLE(CL, IDX) \
+ CLASS_CONST_LONG(CL, IDX)
+/* The first uint16 of the INDEX'th constant pool entry. */
+#define CLASS_CONST_USHORT1(CL, INDEX) ((CL)->constants.data[INDEX] & 0xFFFF)
+/* The second uint16 of the INDEX'th constant pool entry. */
+#define CLASS_CONST_USHORT2(CL, INDEX) \
+ ((uint16)((CL)->constants.data[INDEX] >> 16))
+
+
+/*
+ * 'processClass' is the core of the class initialiser and can prepare a
+ * class from the cradle to the grave.
+ */
+bool processClass(Hjava_lang_Class*, int, errorInfo *einfo);
+
+Hjava_lang_Class* loadClass(Utf8Const*, Hjava_lang_ClassLoader*, errorInfo *einfo);
+Hjava_lang_Class* loadArray(Utf8Const*, Hjava_lang_ClassLoader*, errorInfo *einfo);
+Hjava_lang_Class* findClass(struct _classEntry* centry, errorInfo *einfo);
+
+void loadStaticClass(Hjava_lang_Class**, const char*);
+
+Hjava_lang_Class* setupClass(Hjava_lang_Class*, constIndex,
+ constIndex, u2, Hjava_lang_ClassLoader*, errorInfo*);
+bool addSourceFile(Hjava_lang_Class* c, int idx, errorInfo*);
+bool addInnerClasses(Hjava_lang_Class* c, size_t len, struct classFile* fp, errorInfo *info);
+int startMethods(Hjava_lang_Class*, u2 methct, errorInfo*);
+Method* addMethod(Hjava_lang_Class*, u2 access_flags,
+ u2 name_index, u2 signature_index, errorInfo*);
+Method* addExceptionMethod(Hjava_lang_Class*, Utf8Const*, Utf8Const*);
+void addMethodCode(Method*, struct _Code*);
+Field* addField(Hjava_lang_Class*, u2 access_flags,
+ u2 name_index, u2 signature_index, errorInfo* einfo);
+void addInterfaces(Hjava_lang_Class*, u2, Hjava_lang_Class**);
+void setFieldValue(Hjava_lang_Class*, Field*, u2);
+Hjava_lang_Class* resolveFieldType(Field*, Hjava_lang_Class*, errorInfo*);
+bool getInheritedMethodIndex(Hjava_lang_Class *clazz, Method *meth);
+
+classEntry* lookupClassEntry(Utf8Const*, Hjava_lang_ClassLoader*,
+ errorInfo *info);
+classEntry* lookupClassEntryInternal(Utf8Const*,
+ Hjava_lang_ClassLoader*);
+int removeClassEntries(Hjava_lang_ClassLoader*);
+void walkClassEntries(Collector *collector, void *gc_info, Hjava_lang_ClassLoader*);
+
+Collector* initCollector(void);
+
+Hjava_lang_Class* lookupClass(const char*, Hjava_lang_ClassLoader*,
+ errorInfo*);
+Hjava_lang_Class* lookupArray(Hjava_lang_Class*, errorInfo*);
+Hjava_lang_Class* lookupObjectArrayClass(Hjava_lang_Class*);
+Field* lookupClassField(Hjava_lang_Class*, Utf8Const*, bool, errorInfo *einfo);
+
+void countInsAndOuts(const char*, short*, short*, char*);
+int sizeofSigChar(char, bool);
+int sizeofSigItem(const char**, bool);
+int sizeofSig(const char**, bool);
+int sizeofSigMethod(Method *, bool);
+int sizeofSigClass(Hjava_lang_Class*, bool);
+void establishMethod(Method*);
+Hjava_lang_Class* getClassFromSignature(const char*, Hjava_lang_ClassLoader*, errorInfo*);
+Hjava_lang_Class* getClassFromSignaturePart(const char*, Hjava_lang_ClassLoader*, errorInfo*);
+int countArgsInSignature(const char *);
+parsed_signature_t* parseSignature(Utf8Const *, errorInfo*);
+
+int startFields(Hjava_lang_Class*, u2 fieldct, errorInfo*);
+void finishFields(Hjava_lang_Class*);
+
+void destroyClassLoader(Collector *, void *);
+struct Hjava_lang_String* resolveString(Hjava_lang_Class* clazz, int idx,
+ errorInfo *einfo);
+int findPackageLength(const char *name);
+/*
+ * Start a search for a class. If no other thread is searching for this
+ * mapping then the responsibility falls on the current thread.
+ *
+ * ce - The mapping to start searching for.
+ * out_cl - A placeholder for the class if it has already been bound.
+ * einfo - An uninitialized errorInfo object.
+ * returns - True, if the class is already bound or if this thread should be
+ * responsible for searching/loading the class. False, if searching for this
+ * class would result in a class circularity.
+ */
+int classMappingSearch(classEntry *ce,
+ Hjava_lang_Class **out_cl,
+ errorInfo *einfo);
+/*
+ * Start loading a class.
+ *
+ * ce - The mapping to start searching for.
+ * out_cl - A placeholder for the class if it has already been bound.
+ * einfo - An uninitialized errorInfo object.
+ * returns - True, if the class is already bound or if this thread should be
+ * responsible for searching/loading the class. False, if searching for this
+ * class would result in a class circularity.
+ */
+int classMappingLoad(classEntry *ce,
+ Hjava_lang_Class **out_cl,
+ errorInfo *einfo);
+/*
+ * Transition a mapping to the loaded state.
+ *
+ * ce - The name mapping whose state should be updated.
+ * cl - The class object that should be bound to this mapping.
+ * return - The value of "cl" if the mapping wasn't already updated, otherwise,
+ * it will be the value previously stored in the mapping.
+ */
+Hjava_lang_Class *classMappingLoaded(classEntry *ce, Hjava_lang_Class *cl);
+/*
+ * Force a mapping to a particular state.
+ *
+ * ce - The name mapping whose state should be updated.
+ * nms - The state the mapping should be set to.
+ */
+void setClassMappingState(classEntry *ce, name_mapping_state_t nms);
+
+void walkClassPool(int (*walker)(Hjava_lang_Class *clazz, void *), void *param);
+
+void KaffeVM_initClassPool(void);
+
+extern Utf8Const* init_name; /* "<clinit>" */
+extern Utf8Const* constructor_name; /* "<init>" */
+extern Utf8Const* final_name; /* "finalize" */
+extern Utf8Const* void_signature; /* "()V" */
+extern Utf8Const* Code_name; /* "Code" */
+extern Utf8Const* LineNumberTable_name; /* "LineNumberTable" */
+extern Utf8Const* LocalVariableTable_name; /* "LocalVariableTable" */
+extern Utf8Const* ConstantValue_name; /* "ConstantValue" */
+extern Utf8Const* Exceptions_name; /* "Exceptions" */
+extern Utf8Const* SourceFile_name; /* "SourceFile" */
+extern Utf8Const* InnerClasses_name; /* "InnerClasses" */
+
+#endif
===================================================================
Checking out kaffe/kaffe/kaffevm/gcFuncs.c
RCS: /home/cvs/kaffe/kaffe/kaffe/kaffevm/gcFuncs.c,v
VERS: 1.70
***************
--- /dev/null Sun Aug 4 19:57:58 2002
+++ kaffe/kaffe/kaffevm/gcFuncs.c Tue Apr 12 18:48:29 2005
@@ -0,0 +1,745 @@
+/*
+ * gcFuncs.c
+ * Methods to implement gc-related activities of objects and classes
+ *
+ * Copyright (c) 1996, 1997, 1998, 1999, 2004
+ * Transvirtual Technologies, Inc. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+/*
+ * This file contains those functions that have to do with gc
+ */
+
+#include "config.h"
+#include "debug.h"
+#include "config-std.h"
+#include "config-mem.h"
+#include "defs.h"
+#include "gtypes.h"
+#include "slots.h"
+#include "access.h"
+#include "object.h"
+#include "errors.h"
+#include "code.h"
+#include "file.h"
+#include "readClass.h"
+#include "classMethod.h"
+#include "baseClasses.h"
+#include "stringSupport.h"
+#include "thread.h"
+#include "jthread.h"
+#include "itypes.h"
+#include "bytecode.h"
+#include "exception.h"
+#include "md.h"
+#include "external.h"
+#include "lookup.h"
+#include "support.h"
+#include "gc.h"
+#include "locks.h"
+#include "md.h"
+#include "jni.h"
+#include "soft.h"
+#include "thread.h"
+#include "methodCache.h"
+#include "jvmpi_kaffe.h"
+#include "methodcalls.h"
+
+/*****************************************************************************
+ * Class-related functions
+ */
+
+/*
+ * Destroy a class object.
+ */
+static void
+/* ARGSUSED */
+destroyClass(Collector *collector, void* c)
+{
+ int i;
+ int idx;
+ Hjava_lang_Class* clazz = c;
+ constants* pool;
+
+DBG(CLASSGC,
+ dprintf("destroying class %s @ %p\n",
+ clazz->name ? clazz->name->data : "newborn", c);
+ );
+ assert(!CLASS_IS_PRIMITIVE(clazz));
+
+ /* NB: Make sure that we don't unload fully loaded classes without
+ * classloaders. This is wrong and indicate of a bug.
+ *
+ * NB: Note that this function must destroy any partially
+ * initialized class. Class processing may fail at any
+ * state, and the discarded class objects destroyed.
+ */
+ assert(clazz->state != CSTATE_COMPLETE || clazz->loader != 0);
+
+#if defined(ENABLE_JVMPI)
+ if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_CLASS_UNLOAD) )
+ {
+ JVMPI_Event ev;
+
+ ev.event_type = JVMPI_EVENT_CLASS_UNLOAD;
+ ev.u.class_unload.class_id = c;
+ jvmpiPostEvent(&ev);
+ }
+#endif
+
+ if (Kaffe_JavaVMArgs.enableVerboseGC > 0 && clazz->name) {
+ DBG(CLASSGC,
+ dprintf("<GC: unloading class `%s'>\n",
+ CLASS_CNAME(clazz));
+ );
+ }
+
+ /* destroy all fields */
+ if (CLASS_FIELDS(clazz) != 0) {
+ Field *f = CLASS_FIELDS(clazz);
+ for (i = 0; i < CLASS_NFIELDS(clazz); i++) {
+ utf8ConstRelease(f->name);
+ /* if the field was never resolved, we must release the
+ * Utf8Const to which its type field points */
+ utf8ConstRelease(f->signature);
+ f++;
+ }
+ KFREE(CLASS_FIELDS(clazz));
+ }
+
+ /* destroy all methods, only if this class has indeed a method table */
+ if (!CLASS_IS_ARRAY(clazz) && CLASS_METHODS(clazz) != 0) {
+ Method *m = CLASS_METHODS(clazz);
+ for (i = 0; i < CLASS_NMETHODS(clazz); i++) {
+ void *ncode = NULL;
+
+ if (!CLASS_IS_INTERFACE(clazz))
+ {
+ ncode = METHOD_NATIVECODE(m);
+#if defined(TRANSLATOR) && (defined (MD_UNREGISTER_JIT_EXCEPTION_INFO) || defined (JIT3))
+ if (METHOD_JITTED(m)) {
+#if defined(MD_UNREGISTER_JIT_EXCEPTION_INFO)
+ MD_UNREGISTER_JIT_EXCEPTION_INFO (m->c.ncode.ncode_start,
+ ncode,
+ m->c.ncode.ncode_end);
+#endif
+#if defined(ENABLE_JVMPI)
+ if( JVMPI_EVENT_ISENABLED(JVMPI_EVENT_COMPILED_METHOD_UNLOAD) )
+ {
+ JVMPI_Event ev;
+
+ ev.event_type = JVMPI_EVENT_COMPILED_METHOD_UNLOAD;
+ ev.u.compiled_method_unload.
+ method_id = m;
+ jvmpiPostEvent(&ev);
+ }
+#endif
+ }
+#endif
+ }
+ utf8ConstRelease(m->name);
+ utf8ConstRelease(METHOD_SIG(m));
+ KFREE(METHOD_PSIG(m));
+ KFREE(m->lines);
+ KFREE(m->lvars);
+ if( m->ndeclared_exceptions != -1 )
+ KFREE(m->declared_exceptions);
*** Patch too long, truncated ***
More information about the kaffe
mailing list