dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnet/ilsize ilsize_est.c,NONE,1.1 Makefile.a


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnet/ilsize ilsize_est.c,NONE,1.1 Makefile.am,1.3,1.4 ilsize.c,1.6,1.7
Date: Fri, 18 Apr 2003 05:44:40 -0400

Update of /cvsroot/dotgnu-pnet/pnet/ilsize
In directory subversions:/tmp/cvs-serv11209/ilsize

Modified Files:
        Makefile.am ilsize.c 
Added Files:
        ilsize_est.c 
Log Message:


Add a "class size estimation" feature to ilsize to help
identify how much memory may be needed when loading a class.


--- NEW FILE ---
/*
 * ilsize_est.c - Size estimation for metadata classes.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdio.h>
#include "il_system.h"
#include "il_image.h"
#include "il_program.h"
#include "il_utils.h"
#include "il_dumpasm.h"
#include "../image/image.h"
#include "../image/program.h"

#ifdef  __cplusplus
extern  "C" {
#endif

/*
 * Collected size information structure.
 */
typedef struct
{
        unsigned long   meta;                   /* On-disk metadata size */
        unsigned long   loadedMeta;             /* In-memory metadata size */
        unsigned long   code;                   /* Bytes of method code */

} ILSizeInfo;

/*
 * Get string size information.
 */
static void GetStringSize(ILSizeInfo *info, const char *str)
{
        if(str)
        {
                info->meta += strlen(str) + 1;
        }
}

/*
 * Get blob size information.
 */
static void GetBlobSize(ILSizeInfo *info, ILProgramItem *item, ILUInt32 offset)
{
        unsigned long len;
        unsigned char lenbuf[IL_META_COMPRESS_MAX_SIZE];
        if(ILImageGetBlob(ILProgramItem_Image(item), offset, &len))
        {
                info->meta += len;
                info->meta += (unsigned long)(long)ILMetaCompressData(lenbuf, 
len);
        }
}

/*
 * Get class name size information.
 */
static void GetClassNameSize(ILSizeInfo *info, ILClass *classInfo)
{
        info->meta += sizeof(ILClassName);
        info->meta += strlen(ILClass_Name(classInfo)) + 1;
        if(ILClass_Namespace(classInfo))
        {
                info->meta += strlen(ILClass_Namespace(classInfo)) + 1;
        }
}

/*
 * Get type size information.
 */
static void GetTypeSize(ILSizeInfo *info, ILType *type)
{
        unsigned long num;
        unsigned long posn;

        /* Only complex types have a non-zero memory size */
        if(type == 0 || !ILType_IsComplex(type))
        {
                return;
        }

        /* Account for the size of the complex type header */
        info->loadedMeta += sizeof(ILType);

        /* Account for element information */
        switch(ILType_Kind(type))
        {
                case IL_TYPE_COMPLEX_BYREF:
                case IL_TYPE_COMPLEX_PTR:
                case IL_TYPE_COMPLEX_PINNED:
                {
                        GetTypeSize(info, ILType_Ref(type));
                }
                break;

                case IL_TYPE_COMPLEX_ARRAY:
                case IL_TYPE_COMPLEX_ARRAY_CONTINUE:
                {
                        GetTypeSize(info, ILType_ElemType(type));
                }
                break;

                case IL_TYPE_COMPLEX_CMOD_REQD:
                case IL_TYPE_COMPLEX_CMOD_OPT:
                {
                        GetTypeSize(info, type->un.modifier__.type__);
                }
                break;

                case IL_TYPE_COMPLEX_LOCALS:
                {
                        num = ILTypeNumLocals(type);
                        for(posn = 0; posn < num; ++posn)
                        {
                                GetTypeSize(info, 
ILTypeGetLocalWithPrefixes(type, posn));
                        }
                }
                break;

                case IL_TYPE_COMPLEX_WITH:
                {
                        num = ILTypeNumWithParams(type);
                        GetTypeSize(info, ILTypeGetWithMainWithPrefixes(type));
                        for(posn = 1; posn <= num; ++posn)
                        {
                                GetTypeSize(info, 
ILTypeGetWithParamWithPrefixes(type, posn));
                        }
                }
                break;

                case IL_TYPE_COMPLEX_PROPERTY:
                case IL_TYPE_COMPLEX_METHOD:
                case IL_TYPE_COMPLEX_METHOD | IL_TYPE_COMPLEX_METHOD_SENTINEL:
                {
                        num = ILTypeNumParams(type);
                        GetTypeSize(info, ILTypeGetReturnWithPrefixes(type));
                        for(posn = 1; posn <= num; ++posn)
                        {
                                GetTypeSize(info, 
ILTypeGetParamWithPrefixes(type, posn));
                        }
                }
                break;
        }
}

/*
 * Get the metadata size information for a program item,
 * both on-disk and in-memory.
 */
static void GetMetadataSize(ILSizeInfo *info, ILProgramItem *item)
{
        ILImage *image = ILProgramItem_Image(item);
        if(!item)
        {
                return;
        }
        info->meta += image->tokenSize[ILProgramItem_Token(item) >> 24];
        switch(ILProgramItem_Token(item) & IL_META_TOKEN_MASK)
        {
                case IL_META_TOKEN_MODULE:
                        GetStringSize(info, ILModule_Name((ILModule *)item));
                        info->meta += 16;               /* GUID size */
                        info->loadedMeta += sizeof(ILModule);
                        break;

                case IL_META_TOKEN_MODULE_REF:
                        GetStringSize(info, ILModule_Name((ILModule *)item));
                        info->loadedMeta += sizeof(ILModule);
                        break;

                case IL_META_TOKEN_TYPE_REF:
                        info->loadedMeta += sizeof(ILClass);
                        info->loadedMeta += sizeof(ILProgramItemLink);
                        GetClassNameSize(info, (ILClass *)item);
                        break;

                case IL_META_TOKEN_TYPE_DEF:
                        info->loadedMeta += sizeof(ILClass);
                        GetClassNameSize(info, (ILClass *)item);
                        break;

                case IL_META_TOKEN_FIELD_DEF:
                        info->loadedMeta += sizeof(ILField);
                        GetStringSize(info, ILMember_Name(item));
                        GetBlobSize(info, item, ((ILMember 
*)item)->signatureBlob);
                        GetTypeSize(info, ILMember_Signature(item));
                        break;

                case IL_META_TOKEN_METHOD_DEF:
                        info->loadedMeta += sizeof(ILMethod);
                        GetStringSize(info, ILMember_Name(item));
                        GetBlobSize(info, item, ((ILMember 
*)item)->signatureBlob);
                        GetTypeSize(info, ILMember_Signature(item));
                        break;

                case IL_META_TOKEN_PARAM_DEF:
                        info->loadedMeta += sizeof(ILParameter);
                        GetStringSize(info, ILParameter_Name((ILParameter 
*)item));
                        break;

                case IL_META_TOKEN_INTERFACE_IMPL:
                        info->loadedMeta += sizeof(ILImplements);
                        break;

                case IL_META_TOKEN_MEMBER_REF:
                        if(ILMemberGetKind((ILMember *)item) == 
IL_META_MEMBERKIND_METHOD)
                        {
                                info->loadedMeta += sizeof(ILMethod);
                        }
                        else
                        {
                                info->loadedMeta += sizeof(ILField);
                        }
                        info->loadedMeta += sizeof(ILProgramItemLink);
                        GetStringSize(info, ILMember_Name(item));
                        GetBlobSize(info, item, ((ILMember 
*)item)->signatureBlob);
                        GetTypeSize(info, ILMember_Signature(item));
                        break;

                case IL_META_TOKEN_CONSTANT:
                        info->loadedMeta += sizeof(ILConstant);
                        GetBlobSize(info, item, ((ILConstant *)item)->value);
                        break;

                case IL_META_TOKEN_CUSTOM_ATTRIBUTE:
                        info->loadedMeta += sizeof(ILAttribute);
                        GetBlobSize(info, item, ((ILAttribute *)item)->value);
                        break;

                case IL_META_TOKEN_FIELD_MARSHAL:
                        info->loadedMeta += sizeof(ILFieldMarshal);
                        GetBlobSize(info, item, ((ILFieldMarshal *)item)->type);
                        break;

                case IL_META_TOKEN_DECL_SECURITY:
                        info->loadedMeta += sizeof(ILDeclSecurity);
                        GetBlobSize(info, item, ((ILDeclSecurity *)item)->blob);
                        break;

                case IL_META_TOKEN_CLASS_LAYOUT:
                        info->loadedMeta += sizeof(ILClassLayout);
                        break;

                case IL_META_TOKEN_FIELD_LAYOUT:
                        info->loadedMeta += sizeof(ILFieldLayout);
                        break;

                case IL_META_TOKEN_STAND_ALONE_SIG:
                        info->loadedMeta += sizeof(ILStandAloneSig);
                        GetBlobSize(info, item, ((ILStandAloneSig 
*)item)->typeBlob);
                        GetTypeSize(info, ((ILStandAloneSig *)item)->type);
                        break;

                case IL_META_TOKEN_EVENT_MAP:
                        info->loadedMeta += sizeof(ILEventMap);
                        break;

                case IL_META_TOKEN_EVENT:
                        info->loadedMeta += sizeof(ILEvent);
                        break;

                case IL_META_TOKEN_PROPERTY_MAP:
                        info->loadedMeta += sizeof(ILPropertyMap);
                        break;

                case IL_META_TOKEN_PROPERTY:
                        info->loadedMeta += sizeof(ILProperty);
                        break;

                case IL_META_TOKEN_METHOD_SEMANTICS:
                        info->loadedMeta += sizeof(ILMethodSem);
                        break;

                case IL_META_TOKEN_METHOD_IMPL:
                        info->loadedMeta += sizeof(ILOverride);
                        break;

                case IL_META_TOKEN_TYPE_SPEC:
                        info->loadedMeta += sizeof(ILTypeSpec);
                        GetBlobSize(info, item, ((ILTypeSpec *)item)->typeBlob);
                        GetTypeSize(info, ((ILTypeSpec *)item)->type);
                        break;

                case IL_META_TOKEN_IMPL_MAP:
                        info->loadedMeta += sizeof(ILPInvoke);
                        GetStringSize(info, ILPInvoke_Alias((ILPInvoke *)item));
                        break;

                case IL_META_TOKEN_FIELD_RVA:
                        info->loadedMeta += sizeof(ILFieldRVA);
                        break;

                case IL_META_TOKEN_ASSEMBLY:
                        info->loadedMeta += sizeof(ILAssembly);
                        GetStringSize(info, ILAssembly_Name((ILAssembly 
*)item));
                        GetStringSize(info, ILAssembly_Locale((ILAssembly 
*)item));
                        break;

                case IL_META_TOKEN_ASSEMBLY_REF:
                        info->loadedMeta += sizeof(ILAssembly);
                        info->loadedMeta += sizeof(ILProgramItemLink);
                        GetStringSize(info, ILAssembly_Name((ILAssembly 
*)item));
                        GetStringSize(info, ILAssembly_Locale((ILAssembly 
*)item));
                        break;

                case IL_META_TOKEN_PROCESSOR_DEF:
                case IL_META_TOKEN_PROCESSOR_REF:
                        info->loadedMeta += sizeof(ILProcessorInfo);
                        break;

                case IL_META_TOKEN_OS_DEF:
                case IL_META_TOKEN_OS_REF:
                        info->loadedMeta += sizeof(ILOSInfo);
                        break;

                case IL_META_TOKEN_FILE:
                        info->loadedMeta += sizeof(ILFileDecl);
                        GetStringSize(info, ILFileDecl_Name((ILFileDecl 
*)item));
                        GetBlobSize(info, item, ((ILFileDecl *)item)->hash);
                        break;

                case IL_META_TOKEN_EXPORTED_TYPE:
                        info->loadedMeta += sizeof(ILExportedType);
                        info->loadedMeta += sizeof(ILProgramItemLink);
                        GetClassNameSize(info, (ILClass *)item);
                        break;

                case IL_META_TOKEN_MANIFEST_RESOURCE:
                        info->loadedMeta += sizeof(ILManifestRes);
                        GetStringSize(info, ILManifestRes_Name((ILManifestRes 
*)item));
                        break;

                case IL_META_TOKEN_NESTED_CLASS:
                        info->loadedMeta += sizeof(ILNestedInfo);
                        break;

                case IL_META_TOKEN_GENERIC_PAR:
                        info->loadedMeta += sizeof(ILGenericPar);
                        GetStringSize(info, ILGenericPar_Name((ILGenericPar 
*)item));
                        break;

                case IL_META_TOKEN_METHOD_SPEC:
                        info->loadedMeta += sizeof(ILMethodSpec);
                        GetBlobSize(info, item, ((ILMethodSpec 
*)item)->typeBlob);
                        GetTypeSize(info, ((ILMethodSpec *)item)->type);
                        break;
        }
}

/*
 * Get metadata size information for an item, plus all of its attributes.
 */
static void GetMetadataSizeWithAttrs(ILSizeInfo *info, ILProgramItem *item)
{
        ILAttribute *attr;
        ILDeclSecurity *decl;

        /* Get the basic size information for the item */
        GetMetadataSize(info, item);

        /* Collect up size information for the attributes */
        attr = 0;
        while((attr = ILProgramItemNextAttribute(item, attr)) != 0)
        {
                GetMetadataSize(info, ILToProgramItem(attr));
        }

        /* Account for the security declaration if there is one */
        decl = ILDeclSecurityGetFromOwner(item);
        if(decl)
        {
                GetMetadataSize(info, ILToProgramItem(decl));
        }
}

/*
 * Get metadata size information for a method.
 */
static void GetMethodSize(ILSizeInfo *info, ILMethod *method)
{
        ILParameter *param;
        ILMethodCode code;

        /* Account for the parameters */
        param = 0;
        while((param = ILMethodNextParam(method, param)) != 0)
        {
                GetMetadataSizeWithAttrs(info, ILToProgramItem(param));
        }

        /* Get information about the method's code */
        if(ILMethodGetCode(method, &code))
        {
                info->code += code.codeLen;
                /* TODO: exception block information */
        }
}

/*
 * Get the full size information for a class and its members.
 */
static void GetClassSize(ILSizeInfo *info, ILClass *classInfo)
{
        ILImage *image = ILProgramItem_Image(classInfo);
        ILImplements *impl;
        ILClassLayout *layout;
        ILMember *member;
        int hasEvents, hasProperties;
        ILFieldLayout *fieldLayout;
        ILFieldRVA *fieldRVA;
        ILConstant *constant;
        ILUInt32 type;

        /* Get the size information for the class itself */
        GetMetadataSizeWithAttrs(info, ILToProgramItem(classInfo));

        /* Collect up size information for the interface declarations */
        impl = 0;
        while((impl = ILClassNextImplements(classInfo, impl)) != 0)
        {
                GetMetadataSize(info, ILToProgramItem(impl));
        }

        /* Account for class layout information */
        layout = ILClassLayoutGetFromOwner(classInfo);
        if(layout)
        {
                GetMetadataSize(info, ILToProgramItem(layout));
        }

        /* Account for the nested class declaration */
        if(ILClass_NestedParent(classInfo) != 0)
        {
                info->meta += image->tokenSize[IL_META_TOKEN_NESTED_CLASS >> 
24];
                info->loadedMeta += sizeof(ILNestedInfo);
        }

        /* Collect up size information for the members */
        member = 0;
        hasEvents = 0;
        hasProperties = 0;
        while((member = ILClassNextMember(classInfo, member)) != 0)
        {
                /* Get the basic member size information */
                GetMetadataSizeWithAttrs(info, ILToProgramItem(member));

                /* Deal with additional information hanging off the member */
                switch(ILMemberGetKind(member))
                {
                        case IL_META_MEMBERKIND_METHOD:
                        {
                                GetMethodSize(info, (ILMethod *)member);
                        }
                        break;

                        case IL_META_MEMBERKIND_FIELD:
                        {
                                /* Account for field layout, RVA, and constant 
information */
                                fieldLayout = 
ILFieldLayoutGetFromOwner((ILField *)member);
                                if(fieldLayout)
                                {
                                        GetMetadataSize(info, 
ILToProgramItem(fieldLayout));
                                }
                                fieldRVA = ILFieldRVAGetFromOwner((ILField 
*)member);
                                if(fieldRVA)
                                {
                                        GetMetadataSize(info, 
ILToProgramItem(fieldRVA));
                                }
                                constant = 
ILConstantGetFromOwner((ILProgramItem *)member);
                                if(constant)
                                {
                                        GetMetadataSize(info, 
ILToProgramItem(constant));
                                }
                        }
                        break;

                        case IL_META_MEMBERKIND_PROPERTY:
                        case IL_META_MEMBERKIND_EVENT:
                        {
                                /* Account for the method semantics 
declarations */
                                type = 0x8000;
                                while(type != 0)
                                {
                                        
if(ILMethodSemGetByType(ILToProgramItem(member), type))
                                        {
                                                info->meta +=
                                                        image->tokenSize
                                                                
[IL_META_TOKEN_METHOD_SEMANTICS >> 24];
                                                info->loadedMeta += 
sizeof(ILMethodSem);
                                        }
                                        type >>= 1;
                                }
                                if(ILMemberGetKind(member) == 
IL_META_MEMBERKIND_EVENT)
                                {
                                        hasEvents = 1;
                                }
                                else
                                {
                                        hasProperties = 1;
                                }
                        }
                        break;
                }
        }

        /* If we have events or properties, then account for the map entries */
        if(hasEvents)
        {
                info->meta += image->tokenSize[IL_META_TOKEN_EVENT_MAP >> 24];
                info->loadedMeta += sizeof(ILEventMap);
        }
        if(hasProperties)
        {
                info->meta += image->tokenSize[IL_META_TOKEN_PROPERTY_MAP >> 
24];
                info->loadedMeta += sizeof(ILPropertyMap);
        }
}

/*
 * Type the size information for the classes in an image.
 */
void _ILDumpClassSizes(ILImage *image)
{
        ILClass *classInfo = 0;
        ILSizeInfo info;
        while((classInfo = (ILClass *)ILImageNextToken
                                (image, IL_META_TOKEN_TYPE_DEF, classInfo)) != 
0)
        {
                info.meta = 0;
                info.loadedMeta = 0;
                info.code = 0;
                GetClassSize(&info, classInfo);
                printf("%7lu %7lu %7lu ", info.meta, info.loadedMeta, 
info.code);
                ILDumpClassName(stdout, image, classInfo, 0);
                putc('\n', stdout);
        }
}

#ifdef  __cplusplus
};
#endif

Index: Makefile.am
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/ilsize/Makefile.am,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** Makefile.am 4 Jul 2002 04:59:12 -0000       1.3
--- Makefile.am 18 Apr 2003 09:44:37 -0000      1.4
***************
*** 2,7 ****
  man_MANS       = ilsize.1
  EXTRA_DIST     = $(man_MANS)
! ilsize_SOURCES = ilsize.c
! ilsize_LDADD   = ../image/libILImage.a ../support/libILSupport.a
  
  AM_CFLAGS = -I$(top_srcdir)/include
--- 2,8 ----
  man_MANS       = ilsize.1
  EXTRA_DIST     = $(man_MANS)
! ilsize_SOURCES = ilsize.c ilsize_est.c
! ilsize_LDADD   = ../dumpasm/libILDumpAsm.a \
!                                ../image/libILImage.a ../support/libILSupport.a
  
  AM_CFLAGS = -I$(top_srcdir)/include

Index: ilsize.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/ilsize/ilsize.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** ilsize.c    18 Feb 2003 10:44:14 -0000      1.6
--- ilsize.c    18 Apr 2003 09:44:37 -0000      1.7
***************
*** 43,46 ****
--- 43,47 ----
                "Set the output radix to hexadecimal (16)."},
        {"-D", 'D', 0, 0, 0},
+       {"-c", 'c', 0, 0, 0},
        {"-v", 'v', 0, 0, 0},
        {"-V", 'v', 0, 0, 0},
***************
*** 49,56 ****
                "Define the output radix.  The default is 10."},
        {"--detailed", 'D', 0,
!               "--detailed or -D",
                "Use a more detailed form of output."},
        {"--version", 'v', 0,
!               "--version or -v or -V",
                "Print the version of the program."},
        {"--help", 'h', 0,
--- 50,60 ----
                "Define the output radix.  The default is 10."},
        {"--detailed", 'D', 0,
!               "--detailed    or -D",
!               "Use a more detailed form of output."},
!       {"--class-sizes", 'c', 0,
!               "--class-sizes or -c",
                "Use a more detailed form of output."},
        {"--version", 'v', 0,
!               "--version     or -v or -V",
                "Print the version of the program."},
        {"--help", 'h', 0,
***************
*** 64,67 ****
--- 68,72 ----
  static int printSizes(const char *filename, ILContext *context, int radix);
  static int printDetailed(const char *filename, ILContext *context, int radix);
+ static int printClassSizes(const char *filename, ILContext *context);
  
  int main(int argc, char *argv[])
***************
*** 70,73 ****
--- 75,79 ----
        int radix = 10;
        int detailed = 0;
+       int classSizes = 0;
        int sawStdin;
        int state, opt;
***************
*** 119,122 ****
--- 125,134 ----
                        break;
  
+                       case 'c':
+                       {
+                               classSizes = 1;
+                       }
+                       break;
+ 
                        case 'v':
                        {
***************
*** 151,155 ****
  
        /* Print the headers */
!       if(!detailed)
        {
                printf("   code    meta     res   other     %s     %s 
filename\n",
--- 163,171 ----
  
        /* Print the headers */
!       if(classSizes)
!       {
!               printf("   meta  loaded    code      class\n");
!       }
!       else if(!detailed)
        {
                printf("   code    meta     res   other     %s     %s 
filename\n",
***************
*** 172,175 ****
--- 188,195 ----
                                        errors |= printDetailed("-", context, 
radix);
                                }
+                               else if(classSizes)
+                               {
+                                       errors |= printClassSizes("-", context);
+                               }
                                else
                                {
***************
*** 186,189 ****
--- 206,213 ----
                                errors |= printDetailed(argv[1], context, 
radix);
                        }
+                       else if(classSizes)
+                       {
+                               errors |= printClassSizes(argv[1], context);
+                       }
                        else
                        {
***************
*** 418,421 ****
--- 442,479 ----
        /* Add some space between multiple files */
        printf("\n\n");
+ 
+       /* Clean up and exit */
+       ILImageDestroy(image);
+       return 0;
+ }
+ 
+ /*
+  * Import a function from "ilsize_est.c".
+  */
+ void _ILDumpClassSizes(ILImage *image);
+ 
+ /*
+  * Load an IL image from an input stream and print class size information.
+  */
+ static int printClassSizes(const char *filename, ILContext *context)
+ {
+       ILImage *image;
+       unsigned long total;
+       unsigned long code;
+       unsigned long meta;
+       unsigned long res;
+       unsigned long other;
+ 
+       /* Attempt to load the image into memory */
+       image = loadImage(filename, context,
+                                         IL_LOADFLAG_FORCE_32BIT | 
IL_LOADFLAG_NO_RESOLVE,
+                                         &total, &code, &meta, &res, &other);
+       if(!image)
+       {
+               return 1;
+       }
+ 
+       /* Print the class size information */
+       _ILDumpClassSizes(image);
  
        /* Clean up and exit */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]