typeid_impl.h

来自「This is a resource based on j2me embedde」· C头文件 代码 · 共 386 行

H
386
字号
/* * @(#)typeid_impl.h	1.32 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * *//* * This file gives the interface to the type system. */#ifndef _INCLUDED_TYPEID_IMPL_H#define _INCLUDED_TYPEID_IMPL_H/* * Internal data structures of the CVM type system. * These need only be exported for ROMizer support. * The external interface to the type system is defined in * typeid.h */typedef CVMUint8	TypeidState;#define TYPEID_STATE_INROM	1#define INROM		TYPEID_STATE_INROM#ifdef CVM_DEBUG/* * For purposes of debugging, we tag many table entries * with a state: inRom, added, deleted. * These are manipulated only when the entry is added/deleted * from the table (not just another reference made), and * can be cleared by CVMtypeidPrintDiffs(), c.f. * It works best with NO_RECYCLE turned on as well. */#define TYPEID_STATE_ADDED	2#define TYPEID_STATE_DELETED	4/* Note the ; and , at the end of the following! */#define STATEFLAG(t)	TypeidState t;#define ROMSTATE	TYPEID_STATE_INROM,#else#define STATEFLAG(t)#define ROMSTATE#endif/* * This value is used to signify no-such-entry when an index * is required. Since 0 is, in some places, a valid index, we * use this value instead: */#define TYPEID_NOENTRY ((CVMTypeIDTypePart)-1)/* * This idiom is used in many places to build an extensable, * indexable data structure. This allows us to reference many * of these types as little indices, rather than as full pointers. * It only works if they are of uniform size (or can be shoe-horned into * a uniform-size scheme. Note that the next pointer is a segment **, * which makes for better ROMization of the table segment itself. * See usage examples below. */#define SEGMENT_HEADER(T)	\    int		firstIndex;	\    int		nFree;		\    int		nextFree;	\    int		nInSegment;	\    T **	next;/* * This idiom is used for many of the table entries. * All the tables are adminstered in the same way: reference counted * entries, found by following a a hash bucket chain * that uses an index rather than a direct pointer (strictly space vs. time). *  * Beyond that they're different. The macro is included in the definitions * rather than the struct because of C's alignment rules: if the next entry * is byte-sized, there need not be any padding using the macro, but there probably * would be, using the struct. * * Entries are reference counted, for possible reuse. When a reference * count reaches 255, it sticks, and that entry becomes permenent. ROM * entries should be flagged with a count of 255. A reference count of 0 * flags a free entry. See MAX_COUNT */#define COMMON_TYPE_ENTRY_HEADER \    CVMTypeIDPart	nextIndex;	/* hash bucket chain */ \    CVMUint8		refCount; \    STATEFLAG( state )/* * The basic decoding of the scalarType cookie is described in * scalarType.h.  When that cookie includes an index to a larger table * entry, that entry is a struct scalarTableEntry, which is in a * scalarEntrySegment. *  * Scalar types are also used as classname cookies, since, for the vast * majority of classes, there is at least one scalar holding an instance * of the class type, (and thus a scalar type corresponding to the class) * it seemed economic to unify the two. *  * There are only two entry types: big arrays and classes. It seems * wasteful to use a whole byte for the tag, but alignment constraints are * probably going to cause it to be wasted on padding otherwise. *  */#include "javavm/include/typeid.h"struct pkg; /* see below */struct scalarTableEntry {    COMMON_TYPE_ENTRY_HEADER    CVMUint8			tag;    CVMUint8			nameLength; /* only used for classnameType */    union valueUnion{	struct classnameType {	    struct pkg *	package;	    const char *        classInPackage;	} className;	struct arrayType{	    /* The following two fields must be the same size as those	     * in the className struct above in order for the INIT_ARRAYTYPE	     * macro below to work properly. That is why the CVMAddr	     * type is used.	     */	    CVMAddr	depth;	    CVMAddr	basetype;	} bigArray;    } value;};/* type tags for the union */#define CVM_TYPE_ENTRY_FREE	0#define CVM_TYPE_ENTRY_OBJ	1#define CVM_TYPE_ENTRY_ARRAY	2#define INIT_CLASSTYPE( hashnext, pkgname, myname, length ) \    { hashnext, MAX_COUNT, ROMSTATE CVM_TYPE_ENTRY_OBJ, length, {{ pkgname, myname }}}#define INIT_ARRAYTYPE( hashnext, depth, base ) \    { hashnext, MAX_COUNT, ROMSTATE CVM_TYPE_ENTRY_ARRAY, 0, \      {{ (struct pkg*)depth, (const char*)base }} }/**************************************************************************** * type structures are allocated in arrays, called segments, * which are linked together. * They are allocated, reference counted, freed, and re-used. * Since the segments are of variable size, the ROMizer needs only to * produce one big one of these. * >>Note the extra indirection required for the "next" pointer. This allows * the segment to be ReadOnly, even though the next pointer won't be! */#define SCALAR_TABLE_SEGMENT_HEADER SEGMENT_HEADER(struct scalarTableSegment)struct scalarTableSegment {    SCALAR_TABLE_SEGMENT_HEADER    struct scalarTableEntry		data[1]; /* variable size */};/* * CVMtypeTable points to the first scalarTableSegment. */#ifndef IN_ROMJAVAextern struct scalarTableSegment CVMFieldTypeTable;#endif#define FIRST_SCALAR_TABLE_INDEX CVMtypeLastScalar+1/**************************************************************************** * The basis of type-structure lookup is the package. * This introduces another layer of data-structure management. * Packages are looked up using an initial hash of the name into * a table. Then each package itself contains a mini-hash table for * looking up the scalarTableEntry's. * These packages cannot be ReadOnly, as they contain hash tables, which are * administred by add-at-beginning-of-chain, so the entries can be ReadOnly. * These are reference counted. */#define NCLASSHASH	11#define NPACKAGEHASH	17struct pkg {    const char *	pkgname;    struct pkg *	next;	/* hash bucket chain */    TypeidState		state; /* to hold INROM flag if no other */    CVMUint8	 	refCount;    CVMTypeIDTypePart	typeData[NCLASSHASH];};extern struct pkg ** const CVM_pkgHashtable;extern struct pkg * const CVMnullPackage; /* classes without packages go here. *//************************************************************* * A Form, a.k.a. Terse Signature, has two uses:  * (a) as part of method signatures, it increases sharing of these types. * (b) for JNI parameter passing. *  * A form is a variable-length array of type code 'syllables', one for the * return value and one for each parameter. The encoding we use is the * scalar type encoding, with CVM_TYPEID_OBJ standing for all heap types: * objects and all arrays. *  * The lowest-order syllable of the first word is that of the return * type.  The syllable ajacent to that is for the first parameter.  The * syllable ajacent to that is for the second parameter.  And so on. *  * Since most signature types have fewer than 7 parameters, most * form encodings will fit in one word. These are included in the * method signature directly. All that remains are of the bigger * type. * * There are very few forms. They come and go very slowly. * There is no point in keeping them in an indexed array. */ #define DECLARE_SIG_FORM_N( NAME, N ) \    struct NAME{ \	struct sigForm * next;	/* hash bucket chain */ \	CVMUint8	 refCount; \	STATEFLAG(state)	\	CVMUint8	 nParameters; \	/* may be 2 bytes wasted here, depending on target alignment requirements */ \	CVMUint32	 data[N]; \    }DECLARE_SIG_FORM_N( sigForm, 1 );/* #define FORM_SIZE_INCREMENT (sizeof(struct sigForm) / sizeof(unsigned int)) */#define FORM_SYLLABLESPERDATUM (2*sizeof(CVMUint32))#define FORM_DATAWORDS(n) (((n)+FORM_SYLLABLESPERDATUM-1)/FORM_SYLLABLESPERDATUM)/* * If most forms are small enough to fit within the signatures, * then managing the few that don't isn't very important. * They are variable sized structurs, that I link together. * There as so very few (a dozen?) that I don't even bother * with a hash table. Reference counting is good, though. * When adding new ones, add at the front of the list. * This way, though the CVMformTable cell has to be writable, * the forms themselves can be in ROM. *//* * CVMformTable points to the first sigForm */extern struct sigForm ** const CVMformTablePtr;/******************************************************************* * A method signature is a form reference plus an array of data types, * which correspond to the "Object" items in the form. Of course, they * may be either class types or array types, as both are objects. * These are intrinsically variable-sized data, which I arrange as follows: * there is a fixed-sized part which is kept in segmented arrays, similar * to DataTypes. If there are 0<=n<=2 items in the "details" array, * they are kept in a small array directly in the object. For n>2, * there is a pointer to the array, which is union'ed with the in-line * array. This results in no savings in the ROMized case (where we should * use sharing of sequence prefixes of detail arrays anyway), but * should result in savings for dynamically-created signatures (for which * sharing of details is probably too much bother). * If the signature is short (nSyllables<=8, i.e. 7 or fewer parameters) * then the form is included directly in the signature structure. * Otherwise, there is a pointer to one of the above sigForm things. * The length of the details array is not given here: it can be * derived by inspecting the form. */#define METHOD_TYPE_HEADER \    COMMON_TYPE_ENTRY_HEADER \    CVMUint8		nParameters; /* needed for inline form */#define N_METHOD_INLINE_DETAILS	2struct methodTypeTableEntry {    METHOD_TYPE_HEADER    union methodFormUnion {	struct sigForm *	formp;	CVMUint32		formdata;    } form;    union methodDetailUnion {	CVMTypeIDTypePart	data[N_METHOD_INLINE_DETAILS];	CVMTypeIDTypePart *	datap;    } details;};/******************************************************************** * The indexable table of these things. */#define METHOD_TABLE_SEGMENT_HEADER SEGMENT_HEADER(struct methodTypeTableSegment)struct methodTypeTableSegment {    METHOD_TABLE_SEGMENT_HEADER    struct methodTypeTableEntry		data[1]; /* variable size */};#ifndef IN_ROMJAVAextern struct methodTypeTableSegment CVMMethodTypeTable;#endif/* * And the hash table that starts our search. * NOTE that its a table of indices, not a table of pointers. *//*  * IMPORTANT: * When you change this number also change it in CVMMethodType in jcc. */#define NMETHODTYPEHASH	(13*37) /* arbitrary odd number */extern CVMTypeIDPart * const CVMMethodTypeHash;/******************************************************************** * The member name table. Hashed, reference counted, * indexed. Just like all the above. */struct memberName {    COMMON_TYPE_ENTRY_HEADER    const char *	name;};#define MEMBER_NAME_TABLE_SEGMENT_HEADER SEGMENT_HEADER(struct memberNameTableSegment)struct memberNameTableSegment{    MEMBER_NAME_TABLE_SEGMENT_HEADER    struct memberName	data[1]; /* of variable size */};#define NMEMBERNAMEHASH	(41*13)	/* pretty arbitrary odd number */extern CVMTypeIDPart * const CVMMemberNameHash;#ifndef IN_ROMJAVAextern struct memberNameTableSegment CVMMemberNames;#endif/******************************************************************** * Here for the convenience of several of the C functions.  * Many entries are reference counted, for possible reuse. * When a reference count reaches 255, it sticks, and that entry * becomes permenent. * ROM entries should be flagged with a count of 255. */#define MAX_COUNT ((CVMUint8)0xff)#define conditionalIncRef( ep ) \    {if ( (ep)->refCount < MAX_COUNT ) \	(ep)->refCount += 1; }#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?