Logo Search packages:      
Sourcecode: jmp version File versions  Download package

cls.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <jvmpi.h>

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <cls.h>
#include <translate.h>
#include <filter.h>

#define max(a,b) (a) > (b) ? (a) : (b);

/* TODO, get a dynamic size... */
static char buf[1000];

static void copy_fields (const jint n_statics, field* fields, const JVMPI_Field* origs) {
    jint i;
    size_t l;
    for (i = 0; i < n_statics; i++) {
      fields[i].field_name = strdup (origs[i].field_name);
      fields[i].field_type = NULL;
      switch (origs[i].field_signature[0]) {
      case 'L':
          l = translate_field_type (origs[i].field_signature + 1, buf);
          buf[l - 1] = '\0';   /* remove trailing ';' */
          fields[i].field_type = strdup (buf);
          fields[i].type = JVMPI_NORMAL_OBJECT;
          break;
      case '[':
          translate_field_type (origs[i].field_signature + 1, buf);
          l = translate_field_type (origs[i].field_signature, buf);
          fields[i].field_type = strdup (buf);
          fields[i].type = JVMPI_CLASS;
          break;
      case 'Z':
          fields[i].type = JVMPI_BOOLEAN;
          break;
      case 'B':
          fields[i].type = JVMPI_BYTE;
          break;
      case 'C':
          fields[i].type = JVMPI_CHAR;
          break;
      case 'S':
          fields[i].type = JVMPI_SHORT;
          break;
      case 'I':
          fields[i].type = JVMPI_INT;
          break;
      case 'J':
          fields[i].type = JVMPI_LONG;
          break;
      case 'F':
          fields[i].type = JVMPI_FLOAT;
          break;
      case 'D':
          fields[i].type = JVMPI_DOUBLE;
          break;
      }
    }
}

cls* cls_new (const char* class_name, const char* source_name, const jobjectID class_id,
            const jint n_interfaces, 
            const jint n_statics, const JVMPI_Field* statics,              /* static variables. */
            const jint n_instances, const JVMPI_Field* instances) {        /* local variables. */
    cls* c;
    size_t l2 = 1, l3 = 1;
    
    c = calloc (1, sizeof (*c));
    if (c == NULL)
      return NULL;
    
    if (source_name)
      l2 = strlen (source_name) + 1;
    
    translate_field_type (class_name, buf);
    l3 = strlen (buf) + 1;
    
    c->class_name = strdup (class_name);
    c->source_name = malloc (l2);
    c->name = malloc (l3);
    
    if (c->class_name == NULL ||
      c->source_name == NULL || 
      c->name == NULL) {
      cls_free (c);
      return NULL;
    }
    strncpy (c->name, buf, l3);
    if (source_name)
      strncpy (c->source_name, source_name, l2);
    else 
      c->source_name[0] = '\0';
    c->class_id = class_id;
    
    c->n_interfaces = n_interfaces;
    if (n_interfaces)
      c->interfaces = malloc (n_interfaces * sizeof (*c->interfaces));
    c->n_statics = n_statics;
    if (n_statics)
      c->statics = malloc (n_statics * sizeof (field));
    else 
      c->statics = NULL;
    c->n_instances = n_instances;
    if (n_instances)
      c->instances = malloc (n_instances * sizeof (field));
    else 
      c->instances = NULL;
    if ((n_statics > 0 && c->statics == NULL) || 
      (n_instances > 0 && c->instances == NULL)) {
      c->n_statics = 0;
      c->n_instances = 0;
      cls_free (c);
      return NULL;
    }
    copy_fields (n_statics, c->statics, statics);
    copy_fields (n_instances, c->instances, instances);
    c->super = NULL;
    c->filtered = filter_class_name (c->class_name);
    return c;
}

void cls_free (cls* c) {
    jint i;
    if (c == NULL)
      return;
    free (c->name);
    free (c->source_name);
    free (c->class_name);
    for (i = 0; i < c->n_statics; i++) {
      free (c->statics[i].field_name);
      free (c->statics[i].field_type);
    }
    free (c->statics);
    for (i = 0; i < c->n_instances; i++) {
      free (c->instances[i].field_name);
      free (c->instances[i].field_type);
    }
    free (c->instances);
    free (c);
}

size_t cls_jmphash_func (void* c, size_t len) {
    cls* cp = (cls*)c;
    return ((long)cp->class_id) % len;
}

int cls_cmp_func (void* c1, void* c2) {
    unsigned int u1, u2;
    cls* cp1;
    cls* cp2;
    cp1 = (cls*)c1;
    cp2 = (cls*)c2;
    u1 = (unsigned int)cp1->class_id;
    u2 = (unsigned int)cp2->class_id;
    return u1 - u2;
}

void cls_print (cls* c) {
    pid_t p = getpid ();
    if (c->usage.totalInstances > 0)
      fprintf (stdout, "%d: CLASS: %s, %p, interfaces: %d, statics: %d instances: %d, %ld, %ld\n",
             p, c->class_name, c->class_id, c->n_interfaces, c->n_statics, c->n_instances,
             c->usage.totalAlloced, c->usage.totalInstances);
}

inline char* cls_get_class_name (cls* c) {
    return c->class_name;
}

inline char* cls_get_source_name (cls* c) {
    return c->source_name;
}

inline char* cls_get_name (cls* c) {
    if (c == NULL)
      return NULL;
    return c->name;
}

inline jobjectID cls_get_class_id (cls* c) {
    return c->class_id;
}

inline void cls_set_class_id (cls* c, jobjectID class_id) {
    c->class_id = class_id;
}

inline long cls_get_instances (cls* c) {
    return c->usage.totalInstances;
}

inline void cls_set_instances (cls* c, long l) {
    c->usage.totalInstances = l;
}

inline long cls_get_max_instances (cls* c) {
    return c->usage.maximumInstances;
}

inline void cls_set_max_instances (cls* c, long l) {
    c->usage.maximumInstances = l;
}

inline long cls_get_size (cls* c) {
    return c->usage.totalAlloced;
}

inline long cls_get_total_gc (cls* c) {
    return c->usage.totalGC;
}

inline long cls_get_tenure (cls* c) {
    return c->usage.totalAllocLevel;
}

inline void cls_set_size (cls* c, long l) {
    c->usage.totalAlloced = l;
}

inline void cls_object_alloc (cls* c, jint size, jint gc_level) {
    c->usage.totalInstances++;
    c->usage.totalAlloced += size;
    c->usage.totalAllocLevel += gc_level;
    c->usage.maximumInstances = max (c->usage.totalInstances, 
                             c->usage.maximumInstances);
    c->modified = 1;
}

inline void cls_object_free (cls* c, jint size, jint gc_level) {
    c->usage.totalInstances--;
    c->usage.totalAlloced -= size;
    c->usage.totalGC++;
    c->usage.totalAllocLevel -= gc_level;
    c->modified = 1;
}

inline void cls_object_free_not_gc (cls* c, jint size) {
    c->usage.totalInstances--;
    c->usage.totalAlloced -= size;
    c->modified = 1;
}

inline void cls_reset_count (cls* c) {
    c->restorer.totalAlloced += c->usage.totalAlloced;
    c->usage.totalAlloced = 0;
    c->restorer.totalInstances += c->usage.totalInstances;
    c->usage.totalInstances = 0;
    c->restorer.maximumInstances += c->usage.maximumInstances;
    c->usage.maximumInstances = 0;
    c->restorer.totalGC += c->usage.totalGC;
    c->usage.totalGC = 0;
    c->modified = 1;
}

inline void cls_restore_count (cls* c) {
    c->usage.totalAlloced += c->restorer.totalAlloced;
    c->restorer.totalAlloced = 0;
    c->usage.totalInstances += c->restorer.totalInstances;
    c->restorer.totalInstances = 0;
    c->usage.maximumInstances += c->restorer.maximumInstances;
    c->restorer.maximumInstances = 0;
    c->usage.totalGC += c->restorer.totalGC;
    c->restorer.totalGC = 0;
    c->modified = 1;
}

inline void cls_set_super (cls* c, cls* super) {
    c->super = super;
}

inline cls* cls_get_super (cls* c) {
    return c->super;
}

inline void cls_set_filtered (cls* c, int filtered) {
    c->filtered = filtered;
}

inline int cls_get_filtered (cls* c) {
    return c->filtered;
}

inline int cls_check_modified (cls* c) {
    return c->modified;
}

inline void cls_set_modified (cls* c, int flag) {
    c->modified = flag;
}

/** Get the field type as a readable string.
 */
char* get_field_type (field* f) {
    switch (f->type) {
    case JVMPI_NORMAL_OBJECT:
      return f->field_type;
    case JVMPI_CLASS: 
      return f->field_type;
    case JVMPI_BOOLEAN: 
      return _("boolean");
    case JVMPI_BYTE:
      return _("byte");
    case JVMPI_CHAR:    
      return _("char");
    case JVMPI_SHORT: 
      return _("short");
    case JVMPI_INT: 
      return _("int");
    case JVMPI_LONG: 
      return _("long");
    case JVMPI_FLOAT: 
      return _("float");
    case JVMPI_DOUBLE: 
      return _("double");
    }
    return _("<unknown>");
}

/* Emacs Local Variables: */
/* Emacs mode:C */
/* Emacs c-indentation-style:"gnu" */
/* Emacs c-hanging-braces-alist:((brace-list-open)(brace-entry-open)(defun-open after)(substatement-open after)(block-close . c-snug-do-while)(extern-lang-open after)) */
/* Emacs c-cleanup-list:(brace-else-brace brace-elseif-brace space-before-funcall) */
/* Emacs c-basic-offset:4 */
/* Emacs End: */

Generated by  Doxygen 1.6.0   Back to index