// Profiler.h -- runtime profiler
// 
// Author: Ian.Piumarta@INRIA.Fr
// 
// Last edited: 2000-10-19 08:50:17 by piumarta on emilia.rd.wdi.disney.com

#ifndef _j_Profiler_h
#define _j_Profiler_h


#include "archdep.h"

#include <sys/types.h>

class NativeMethod;
class Profile;

#if !defined(PROFILER)	// we don't got no profiler

#ifndef size_t
# define size_t unsigned int
#endif

typedef unsigned short tally_t;

class Profiler
{
public:
  static void initialise(insn *o, size_t r);
  static void methodBase(insn *b);

  inline static bool isInitialised(void) { return true; }
  inline static bool hasTallies(void) { return false; }
  inline static size_t tallyBytes(void) { return 0; }
  inline static insn *profileLimit(void) { return 0; }
  inline static bool includes(insn *pc) { return false; }
  inline static size_t indexOf(insn *pc) { return 0; }
  inline static insn *addressOf(size_t index) { return 0; }
  inline static size_t maxIndex(void) { return 0; }

  static size_t total(insn *from, insn *to= 0);

  static void allocProfiles(size_t nProfiles);
  static void add(NativeMethod *nm, size_t count);
  static void addTotals(unsigned link, unsigned ic, unsigned ctype,
			unsigned prim, unsigned ctl,
			unsigned activ,	unsigned method, unsigned defer);
  static void profile(size_t observed, size_t expected, float elapsed);

  // Smalltalk primitives

  static void start(void);
  static void stop(void);
  static void clear(void);
  static void dump(void);
};

#else // we got a profiler

class Profiler
{
# if defined(__GLIBC__)
  typedef unsigned short tally_t;
# else
#   error: your OS cannot handle profiling
# endif

public:
  static insn	 *origin;
  static size_t	  range;
  static tally_t *tallies;
  static insn    *base;

  static Profile *profiles;
  static size_t   profileCount;
  static size_t   profilesSize;

  static void initialise(insn *o, size_t r);
  static void methodBase(insn *b);

  inline static bool isInitialised(void)
    {
      return origin != 0;
    }

  inline static bool hasTallies(void)
    {
      return tallies != 0;
    }

  inline static size_t tallyBytes(void)
    {
      return range / sizeof(insn) * sizeof(tally_t);
    }

  inline static insn *profileLimit(void)
    {
      return (insn *)((char *)origin + range);
    }

  inline static bool includes(insn *pc)
    {
      return (pc >= origin) && (pc < profileLimit());
    }

  inline static size_t indexOf(insn *pc)
    {
      return pc - origin;
    }

  inline static insn *addressOf(size_t index)
    {
      return origin + index;
    }

  inline static size_t maxIndex(void)
    {
      return range / sizeof(insn);
    }

  static size_t total(insn *from, insn *to= 0);

  static void allocProfiles(size_t nProfiles);
  static void add(NativeMethod *nm, size_t count);
  static void addTotals(unsigned link, unsigned ic, unsigned ctype,
			unsigned prim, unsigned ctl,
			unsigned activ,	unsigned method, unsigned defer);
  static void profile(size_t observed, size_t expected, float elapsed);

  // Smalltalk primitives

  static void start(void);
  static void stop(void);
  static void clear(void);
  static void dump(void);
};

#endif // !PROFILER

#endif // _j_Profiler_h
