jvm.h 25.9 KB
Newer Older
Tom Tromey committed
1 2
// jvm.h - Header file for private implementation information. -*- c++ -*-

3
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation
Tom Tromey committed
4 5 6 7 8 9 10 11 12 13

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

#ifndef __JAVA_JVM_H__
#define __JAVA_JVM_H__

Tom Tromey committed
14 15 16 17 18 19
// Define this before including jni.h.
// jni.h is included by jvmpi.h, which might be included.  We define
// this unconditionally because it is convenient and it lets other
// files include jni.h without difficulty.
#define __GCJ_JNI_IMPL__

Tom Tromey committed
20 21
#include <gcj/javaprims.h>

Tom Tromey committed
22
#include <java-assert.h>
Tom Tromey committed
23 24 25 26 27 28 29 30 31
#include <java-threads.h>
// Must include java-gc.h before Object.h for the implementation.
#include <java-gc.h>

#include <java/lang/Object.h>

// Include cni.h before field.h to enable all definitions.  FIXME.
#include <gcj/cni.h>
#include <gcj/field.h>
Tom Tromey committed
32

33 34 35 36
#include <java/lang/Thread.h>

#include <sysdep/locks.h>

37 38 39
/* Macro for possible unused arguments.  */
#define MAYBE_UNUSED __attribute__((__unused__))

Tom Tromey committed
40 41 42
/* Structure of the virtual table.  */
struct _Jv_VTable
{
43 44 45 46 47
#ifdef __ia64__
  typedef struct { void *pc, *gp; } vtable_elt;
#else
  typedef void *vtable_elt;
#endif
48 49
  jclass clas;
  void *gc_descr;
50 51 52 53 54 55 56 57

  // This must be last, as derived classes "extend" this by
  // adding new data members.
  vtable_elt method[1];

#ifdef __ia64__
  void *get_method(int i) { return &method[i]; }
  void set_method(int i, void *fptr) { method[i] = *(vtable_elt *)fptr; }
58 59 60 61 62 63 64 65
  void *get_finalizer()
  {
    // We know that get_finalizer is only used for checking whether
    // this object needs to have a finalizer registered.  So it is
    // safe to simply return just the PC component of the vtable
    // slot.
    return ((vtable_elt *)(get_method(0)))->pc;
  }
66 67 68
#else
  void *get_method(int i) { return method[i]; }
  void set_method(int i, void *fptr) { method[i] = fptr; }
69
  void *get_finalizer() { return get_method(0); }
70 71 72
#endif

  static size_t vtable_elt_size() { return sizeof(vtable_elt); }
73 74 75 76 77 78

  // Given a method index, return byte offset from the vtable pointer.
  static jint idx_to_offset (int index)
  {
    return (2 * sizeof (void *)) + (index * vtable_elt_size ());
  }
79

80
  static _Jv_VTable *new_vtable (int count);
Tom Tromey committed
81 82
};

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
union _Jv_word
{
  jobject o;
  jint i;			// Also stores smaller integral types.
  jfloat f;
  jint ia[1];			// Half of _Jv_word2.
  void* p;

#if SIZEOF_VOID_P == 8
  // We can safely put a long or a double in here without increasing
  // the size of _Jv_Word; we take advantage of this in the interpreter.
  jlong l;
  jdouble d;
#endif

  jclass                     clazz;
  jstring                    string;
  struct _Jv_Field          *field;
  struct _Jv_Utf8Const      *utf8;
  struct _Jv_ResolvedMethod *rmethod;
};

union _Jv_word2
{
  jint ia[2];
  jlong l;
  jdouble d;
};                              

112 113 114 115 116 117 118 119 120 121 122 123
union _Jv_value
{
  jbyte byte_value;
  jshort short_value;
  jchar char_value;
  jint int_value;
  jlong long_value;
  jfloat float_value;
  jdouble double_value;
  jobject object_value;
};

Tom Tromey committed
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
/* Extract a character from a Java-style Utf8 string.
 * PTR points to the current character.
 * LIMIT points to the end of the Utf8 string.
 * PTR is incremented to point after the character thta gets returns.
 * On an error, -1 is returned. */
#define UTF8_GET(PTR, LIMIT) \
  ((PTR) >= (LIMIT) ? -1 \
   : *(PTR) < 128 ? *(PTR)++ \
   : (*(PTR)&0xE0) == 0xC0 && ((PTR)+=2)<=(LIMIT) && ((PTR)[-1]&0xC0) == 0x80 \
   ? (((PTR)[-2] & 0x1F) << 6) + ((PTR)[-1] & 0x3F) \
   : (*(PTR) & 0xF0) == 0xE0 && ((PTR) += 3) <= (LIMIT) \
   && ((PTR)[-2] & 0xC0) == 0x80 && ((PTR)[-1] & 0xC0) == 0x80 \
   ? (((PTR)[-3]&0x0F) << 12) + (((PTR)[-2]&0x3F) << 6) + ((PTR)[-1]&0x3F) \
   : ((PTR)++, -1))

139
extern int _Jv_strLengthUtf8(const char* str, int len);
Tom Tromey committed
140 141

typedef struct _Jv_Utf8Const Utf8Const;
142
_Jv_Utf8Const *_Jv_makeUtf8Const (const char *s, int len);
Anthony Green committed
143
_Jv_Utf8Const *_Jv_makeUtf8Const (jstring string);
144 145 146 147
static inline _Jv_Utf8Const *_Jv_makeUtf8Const (const char *s)
{
  return _Jv_makeUtf8Const (s, strlen (s));
}
148
extern jboolean _Jv_equalUtf8Consts (const _Jv_Utf8Const *, const _Jv_Utf8Const *);
Tom Tromey committed
149
extern jboolean _Jv_equal (_Jv_Utf8Const *, jstring, jint);
Tom Tromey committed
150
extern jboolean _Jv_equaln (_Jv_Utf8Const *, jstring, jint);
Tom Tromey committed
151

152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
/* Helper class which converts a jstring to a temporary char*.
   Uses the supplied buffer, if non-null. Otherwise, allocates
   the buffer on the heap. Use the JV_TEMP_UTF_STRING macro,
   which follows, to automatically allocate a stack buffer if
   the string is small enough. */
class _Jv_TempUTFString
{
public:
  _Jv_TempUTFString(jstring jstr, char* buf=0);
  ~_Jv_TempUTFString();

// Accessors
  operator const char*() const
  {
    return buf_;
  }
  const char* buf() const
  {
    return buf_;
  }
  char* buf()
  {
    return buf_;
  }

private:
  char* buf_;
  bool heapAllocated_;
};

inline _Jv_TempUTFString::_Jv_TempUTFString (jstring jstr, char* buf)
  : buf_(0), heapAllocated_(false)
{
  if (!jstr) return;
  jsize len = JvGetStringUTFLength (jstr);
  if (buf)
    buf_ = buf;
  else
    {
      buf_ = (char*) _Jv_Malloc (len+1);
      heapAllocated_ = true;
    }

  JvGetStringUTFRegion (jstr, 0, jstr->length(), buf_);
  buf_[len] = '\0';
}

inline _Jv_TempUTFString::~_Jv_TempUTFString ()
{
  if (heapAllocated_)
    _Jv_Free (buf_);
}

/* Macro which uses _Jv_TempUTFString. Allocates a stack-based
   buffer if the string and its null terminator are <= 256
   characters in length. Otherwise, a heap-based buffer is
   used. The parameters to this macro are the variable name
   which is an instance of _Jv_TempUTFString (above) and a
   jstring.
   
   Sample Usage:
   
   jstring jstr = getAJString();
   JV_TEMP_UTF_STRING(utfstr, jstr);
   printf("The string is: %s\n", utfstr.buf());
   
 */
#define JV_TEMP_UTF_STRING(utfstr, jstr) \
  jstring utfstr##thejstr = (jstr); \
  jsize utfstr##_len = utfstr##thejstr ? JvGetStringUTFLength (utfstr##thejstr) + 1 : 0; \
  char utfstr##_buf[utfstr##_len <= 256 ? utfstr##_len : 0]; \
  _Jv_TempUTFString utfstr(utfstr##thejstr, sizeof(utfstr##_buf)==0 ? 0 : utfstr##_buf)

225 226 227 228 229 230 231
namespace gcj
{
  /* Some constants used during lookup of special class methods.  */
  extern _Jv_Utf8Const *void_signature; /* "()V" */
  extern _Jv_Utf8Const *clinit_name;    /* "<clinit>" */
  extern _Jv_Utf8Const *init_name;      /* "<init>" */
  extern _Jv_Utf8Const *finit_name;     /* "finit$", */
232 233 234
  
  /* Set to true by _Jv_CreateJavaVM. */
  extern bool runtimeInitialized;
235 236 237

  /* Print out class names as they are initialized. */
  extern bool verbose_class_flag;
Bryce McKinlay committed
238 239 240
  
  /* When true, enable the bytecode verifier and BC-ABI verification. */
  extern bool verifyClasses;
Bryce McKinlay committed
241 242 243

  /* Thread stack size specified by the -Xss runtime argument. */
  extern size_t stack_size;
244 245 246 247 248 249 250 251 252 253 254 255

  /* The start time */
  extern jlong startTime;
  
  /* The VM arguments */
  extern JArray<jstring>* vmArgs;

  // Currently loaded classes
  extern jint loadedClasses;

  // Unloaded classes
  extern jlong unloadedClasses;
256
}
257

258 259 260 261
// This class handles all aspects of class preparation and linking.
class _Jv_Linker
{
private:
262 263
  typedef unsigned int uaddr __attribute__ ((mode (pointer)));

264
  static _Jv_Field *find_field_helper(jclass, _Jv_Utf8Const *, _Jv_Utf8Const *,
265
				      jclass, jclass *);
266
  static _Jv_Field *find_field(jclass, jclass, jclass *, _Jv_Utf8Const *,
267
			       _Jv_Utf8Const *);
268
  static void check_loading_constraints (_Jv_Method *, jclass, jclass);
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
  static void prepare_constant_time_tables(jclass);
  static jshort get_interfaces(jclass, _Jv_ifaces *);
  static void link_symbol_table(jclass);
  static void link_exception_table(jclass);
  static void layout_interface_methods(jclass);
  static void set_vtable_entries(jclass, _Jv_VTable *);
  static void make_vtable(jclass);
  static void ensure_fields_laid_out(jclass);
  static void ensure_class_linked(jclass);
  static void ensure_supers_installed(jclass);
  static void add_miranda_methods(jclass, jclass);
  static void ensure_method_table_complete(jclass);
  static void verify_class(jclass);
  static jshort find_iindex(jclass *, jshort *, jshort);
  static jshort indexof(void *, void **, jshort);
  static int get_alignment_from_class(jclass);
  static void generate_itable(jclass, _Jv_ifaces *, jshort *);
  static jshort append_partial_itable(jclass, jclass, void **, jshort);
287 288 289 290 291
  static _Jv_Method *search_method_in_superclasses (jclass cls, jclass klass, 
						    _Jv_Utf8Const *method_name,
 						    _Jv_Utf8Const *method_signature,
						    jclass *found_class,
						    bool check_perms = true);
292
  static void *create_error_method(_Jv_Utf8Const *, jclass);
293

294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
  /* The least significant bit of the signature pointer in a symbol
     table is set to 1 by the compiler if the reference is "special",
     i.e. if it is an access to a private field or method.  Extract
     that bit, clearing it in the address and setting the LSB of
     SPECIAL accordingly.  */
  static void maybe_adjust_signature (_Jv_Utf8Const *&s, uaddr &special)
  {
    union {
      _Jv_Utf8Const *signature;
      uaddr signature_bits;
    };
    signature = s;
    special = signature_bits & 1;
    signature_bits -= special;
    s = signature;
  }  

311 312 313
  static _Jv_Mutex_t resolve_mutex;
  static void init (void) __attribute__((constructor));

314 315
public:

316
  static bool has_field_p (jclass, _Jv_Utf8Const *);
317 318 319
  static void print_class_loaded (jclass);
  static void resolve_class_ref (jclass, jclass *);
  static void wait_for_state(jclass, int);
320 321 322
  static _Jv_Method *resolve_method_entry (jclass, jclass &,
					   int, int,
					   bool, bool);
323
  static _Jv_word resolve_pool_entry (jclass, int, bool =false);
324 325
  static void resolve_field (_Jv_Field *, java::lang::ClassLoader *);
  static void verify_type_assertions (jclass);
326 327 328 329 330
  static _Jv_Method *search_method_in_class (jclass, jclass,
					     _Jv_Utf8Const *,
					     _Jv_Utf8Const *,
					     bool check_perms = true);
  static void layout_vtable_methods(jclass);
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351

  static jbyte read_cpool_entry (_Jv_word *data,
				 const _Jv_Constants *const pool,
				 int index)
  {
    _Jv_MutexLock (&resolve_mutex);
    jbyte tags = pool->tags[index];
    *data = pool->data[index];
    _Jv_MutexUnlock (&resolve_mutex);
    return tags;
  }

  static void write_cpool_entry (_Jv_word data, jbyte tags,
				 _Jv_Constants *pool,
				 int index)
  {
    _Jv_MutexLock (&resolve_mutex);
    pool->data[index] = data;
    pool->tags[index] = tags;
    _Jv_MutexUnlock (&resolve_mutex);
  }
352 353
};

Tom Tromey committed
354 355 356 357
/* Type of pointer used as finalizer.  */
typedef void _Jv_FinalizerFunc (jobject);

/* Allocate space for a new Java object.  */
358
void *_Jv_AllocObj (jsize size, jclass cl) __attribute__((__malloc__));
Tom Tromey committed
359 360 361
/* Allocate space for a potentially uninitialized pointer-free object.
   Interesting only with JV_HASH_SYNCHRONIZATION.  */
void *_Jv_AllocPtrFreeObj (jsize size, jclass cl) __attribute__((__malloc__));
Tom Tromey committed
362
/* Allocate space for an array of Java objects.  */
363
void *_Jv_AllocArray (jsize size, jclass cl) __attribute__((__malloc__));
Tom Tromey committed
364
/* Allocate space that is known to be pointer-free.  */
365
void *_Jv_AllocBytes (jsize size) __attribute__((__malloc__));
366 367 368
/* Allocate space for a new non-Java object, which does not have the usual 
   Java object header but may contain pointers to other GC'ed objects.  */
void *_Jv_AllocRawObj (jsize size) __attribute__((__malloc__));
369 370 371 372
/* Allocate a double-indirect pointer to a _Jv_ClosureList such that
   the _Jv_ClosureList gets automatically finalized when it is no
   longer reachable, not even by other finalizable objects.  */
_Jv_ClosureList **_Jv_ClosureListFinalizer (void) __attribute__((__malloc__));
Tom Tromey committed
373
/* Explicitly throw an out-of-memory exception.	*/
374
void _Jv_ThrowNoMemory() __attribute__((__noreturn__));
Tom Tromey committed
375 376 377
/* Allocate an object with a single pointer.  The first word is reserved
   for the GC, and the second word is the traced pointer.  */
void *_Jv_AllocTraceOne (jsize size /* incl. reserved slot */);
378 379
/* Ditto, but for two traced pointers.			   */
void *_Jv_AllocTraceTwo (jsize size /* incl. reserved slot */);
Tom Tromey committed
380 381 382 383
/* Initialize the GC.  */
void _Jv_InitGC (void);
/* Register a finalizer.  */
void _Jv_RegisterFinalizer (void *object, _Jv_FinalizerFunc *method);
384 385
/* Compute the GC descriptor for a class */
void * _Jv_BuildGCDescr(jclass);
Tom Tromey committed
386

387 388 389 390
/* Allocate some unscanned, unmoveable memory.  Return NULL if out of
   memory.  */
void *_Jv_MallocUnchecked (jsize size) __attribute__((__malloc__));

391 392 393
/* Initialize finalizers.  The argument is a function to be called
   when a finalizer is ready to be run.  */
void _Jv_GCInitializeFinalizers (void (*notifier) (void));
Tom Tromey committed
394 395 396 397 398 399
/* Run finalizers for objects ready to be finalized..  */
void _Jv_RunFinalizers (void);
/* Run all finalizers.  Should be called only before exit.  */
void _Jv_RunAllFinalizers (void);
/* Perform a GC.  */
void _Jv_RunGC (void);
Anthony Green committed
400 401 402
/* Disable and enable GC.  */
void _Jv_DisableGC (void);
void _Jv_EnableGC (void);
403 404 405 406 407 408 409
/* Register a disappearing link.  This is a field F which should be
   cleared when *F is found to be inaccessible.  This is used in the
   implementation of java.lang.ref.Reference.  */
void _Jv_GCRegisterDisappearingLink (jobject *objp);
/* Return true if OBJECT should be reclaimed.  This is used to
   implement soft references.  */
jboolean _Jv_GCCanReclaimSoftReference (jobject obj);
Tom Tromey committed
410

411 412 413 414 415 416
/* Register a finalizer for a String object.  This is only used by
   the intern() implementation.  */
void _Jv_RegisterStringFinalizer (jobject str);
/* This is called to actually finalize a possibly-intern()d String.  */
void _Jv_FinalizeString (jobject str);

Tom Tromey committed
417 418 419 420 421
/* Return approximation of total size of heap.  */
long _Jv_GCTotalMemory (void);
/* Return approximation of total free memory.  */
long _Jv_GCFreeMemory (void);

Tom Tromey committed
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
/* Set initial heap size.  If SIZE==0, ignore.  Should be run before
   _Jv_InitGC.  Not required to have any actual effect.  */
void _Jv_GCSetInitialHeapSize (size_t size);

/* Set maximum heap size.  If SIZE==0, unbounded.  Should be run
   before _Jv_InitGC.  Not required to have any actual effect.  */
void _Jv_GCSetMaximumHeapSize (size_t size);

/* External interface to setting the heap size.  Parses ARG (a number
   which can optionally have "k" or "m" appended and calls
   _Jv_GCSetInitialHeapSize.  */
void _Jv_SetInitialHeapSize (const char *arg);

/* External interface to setting the maximum heap size.  Parses ARG (a
   number which can optionally have "k" or "m" appended and calls
   _Jv_GCSetMaximumHeapSize.  */
void _Jv_SetMaximumHeapSize (const char *arg);

440 441 442 443
/* External interface for setting the GC_free_space_divisor.  Calls
   GC_set_free_space_divisor and returns the old value.  */
int _Jv_SetGCFreeSpaceDivisor (int div);

444 445 446 447
/* Free the method cache, if one was allocated.  This is only called
   during thread deregistration.  */
void _Jv_FreeMethodCache ();

Bryce McKinlay committed
448 449 450 451
/* Set the stack size for threads.  Parses ARG, a number which can 
   optionally have "k" or "m" appended.  */
void _Jv_SetStackSize (const char *arg);

Tom Tromey committed
452
extern "C" void JvRunMain (jclass klass, int argc, const char **argv);
453 454
extern "C" void JvRunMainName (const char *name, int argc, const char **argv);

455 456
void _Jv_RunMain (jclass klass, const char *name, int argc, const char **argv, 
		  bool is_jar);
Tom Tromey committed
457

458 459 460
void _Jv_RunMain (struct _Jv_VMInitArgs *vm_args, jclass klass,
                  const char *name, int argc, const char **argv, bool is_jar);

461
// Delayed until after _Jv_AllocRawObj is declared.
462 463 464 465
inline _Jv_VTable *
_Jv_VTable::new_vtable (int count)
{
  size_t size = sizeof(_Jv_VTable) + (count - 1) * vtable_elt_size ();
466
  return (_Jv_VTable *) _Jv_AllocRawObj (size);
467 468
}

469 470 471 472 473
// Determine if METH gets an entry in a VTable.
static inline jboolean _Jv_isVirtualMethod (_Jv_Method *meth)
{
  using namespace java::lang::reflect;
  return (((meth->accflags & (Modifier::STATIC | Modifier::PRIVATE)) == 0)
474
          && meth->name->first() != '<');
475 476
}

Tom Tromey committed
477 478 479 480
// This function is used to determine the hash code of an object.
inline jint
_Jv_HashCode (jobject obj)
{
481
  // This was chosen to yield relatively well distributed results on
482 483 484
  // both 32- and 64-bit architectures.  Note 0x7fffffff is prime.
  // FIXME: we assume sizeof(long) == sizeof(void *).
  return (jint) ((unsigned long) obj % 0x7fffffff);
Tom Tromey committed
485 486
}

487 488 489
// Return a raw pointer to the elements of an array given the array
// and its element type.  You might think we could just pick a single
// array type and use elements() on it, but we can't because we must
490 491
// account for alignment of the element type.  When ARRAY is null, we
// obtain the number of bytes taken by the base part of the array.
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
inline char *
_Jv_GetArrayElementFromElementType (jobject array,
				    jclass element_type)
{
  char *elts;
  if (element_type == JvPrimClass (byte))
    elts = (char *) elements ((jbyteArray) array);
  else if (element_type == JvPrimClass (short))
    elts = (char *) elements ((jshortArray) array);
  else if (element_type == JvPrimClass (int))
    elts = (char *) elements ((jintArray) array);
  else if (element_type == JvPrimClass (long))
    elts = (char *) elements ((jlongArray) array);
  else if (element_type == JvPrimClass (boolean))
    elts = (char *) elements ((jbooleanArray) array);
  else if (element_type == JvPrimClass (char))
    elts = (char *) elements ((jcharArray) array);
  else if (element_type == JvPrimClass (float))
    elts = (char *) elements ((jfloatArray) array);
  else if (element_type == JvPrimClass (double))
    elts = (char *) elements ((jdoubleArray) array);
  else
    elts = (char *) elements ((jobjectArray) array);
  return elts;
}

518 519 520 521
extern "C" void _Jv_ThrowBadArrayIndex (jint bad_index)
  __attribute__((noreturn));
extern "C" void _Jv_ThrowNullPointerException (void)
  __attribute__((noreturn));
522 523 524 525
extern "C" void _Jv_ThrowNoSuchMethodError (void)
  __attribute__((noreturn));
extern "C" void _Jv_ThrowNoSuchFieldError (int)
  __attribute__((noreturn));
526 527 528 529
extern "C" jobject _Jv_NewArray (jint type, jint size)
  __attribute__((__malloc__));
extern "C" jobject _Jv_NewMultiArray (jclass klass, jint dims, ...)
  __attribute__((__malloc__));
Tom Tromey committed
530 531
extern "C" void *_Jv_CheckCast (jclass klass, jobject obj);
extern "C" void *_Jv_LookupInterfaceMethod (jclass klass, Utf8Const *name,
532 533 534
                                           Utf8Const *signature);
extern "C" void *_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface, 
                                               int meth_idx);
Tom Tromey committed
535 536
extern "C" void _Jv_CheckArrayStore (jobject array, jobject obj);
extern "C" void _Jv_RegisterClass (jclass klass);
537 538 539
extern "C" void _Jv_RegisterClasses (const jclass *classes);
extern "C" void _Jv_RegisterClasses_Counted (const jclass *classes,
					     size_t count);
540
extern "C" void _Jv_RegisterResource (void *vptr);
Anthony Green committed
541 542
extern void _Jv_UnregisterClass (_Jv_Utf8Const*, java::lang::ClassLoader*);

543 544
extern "C" jobject _Jv_UnwrapJNIweakReference (jobject);

Tom Tromey committed
545 546
extern jclass _Jv_FindClass (_Jv_Utf8Const *name,
			     java::lang::ClassLoader *loader);
547 548 549 550

extern jclass _Jv_FindClassNoException (_Jv_Utf8Const *name,
			     java::lang::ClassLoader *loader);

Tom Tromey committed
551
extern jclass _Jv_FindClassFromSignature (char *,
552 553
					  java::lang::ClassLoader *loader,
					  char ** = NULL);
554 555 556 557 558

extern jclass _Jv_FindClassFromSignatureNoException (char *,
					  java::lang::ClassLoader *loader,
					  char ** = NULL);

Tom Tromey committed
559 560 561 562
extern void _Jv_GetTypesFromSignature (jmethodID method,
				       jclass declaringClass,
				       JArray<jclass> **arg_types_out,
				       jclass *return_type_out);
563

Tom Tromey committed
564 565 566
extern jboolean _Jv_CheckAccess (jclass self_klass, jclass other_klass,
				 jint flags);

567 568 569
extern jobject _Jv_CallAnyMethodA (jobject obj, jclass return_type,
				   jmethodID meth, jboolean is_constructor,
				   JArray<jclass> *parameter_types,
Bryce McKinlay committed
570 571
				   jobjectArray args,
				   jclass iface = NULL);
572 573

union jvalue;
574 575 576 577
extern void _Jv_CallAnyMethodA (jobject obj,
				jclass return_type,
				jmethodID meth,
				jboolean is_constructor,
578
				jboolean is_virtual_call,
579
				JArray<jclass> *parameter_types,
580
				const jvalue *args,
581
				jvalue *result,
Bryce McKinlay committed
582 583
				jboolean is_jni_call = true,
				jclass iface = NULL);
Tom Tromey committed
584

585 586 587
extern void _Jv_CheckOrCreateLoadingConstraint (jclass,
						java::lang::ClassLoader *);

588 589
extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
  __attribute__((__malloc__));
Tom Tromey committed
590

591 592
extern "C" void _Jv_ThrowAbstractMethodError () __attribute__((__noreturn__));

593 594 595 596 597 598 599 600 601
/* Checked divide subroutines. */
extern "C"
{
  jint _Jv_divI (jint, jint);
  jint _Jv_remI (jint, jint);
  jlong _Jv_divJ (jlong, jlong);
  jlong _Jv_remJ (jlong, jlong);
}

602 603 604 605 606 607 608 609 610 611 612 613 614 615
/* Get the number of arguments (cf. argc) or 0 if our argument
   list was never initialized.  */
extern int _Jv_GetNbArgs (void);

/* Get the specified argument (cf. argv[index]) or "" if either
   our argument list was never initialized or the specified index
   is out of bounds.  */
extern const char * _Jv_GetSafeArg (int index);

/* Sets our argument list. Can be used by programs with non-standard
   entry points.  */
extern void _Jv_SetArgs (int argc, const char **argv);

/* Get the name of the running executable.  */
Andrew Haley committed
616
extern const char *_Jv_ThisExecutable (void);
617

618 619 620
/* Return a pointer to a symbol in executable or loaded library.  */
void *_Jv_FindSymbolInExecutable (const char *);

621 622 623
/* Initialize JNI.  */
extern void _Jv_JNI_Init (void);

624 625 626 627
/* Get or set the per-thread JNIEnv used by the invocation API.  */
_Jv_JNIEnv *_Jv_GetCurrentJNIEnv ();
void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *);

628 629 630
/* Free a JNIEnv. */
void _Jv_FreeJNIEnv (_Jv_JNIEnv *);

631 632
extern "C" void _Jv_JNI_PopSystemFrame (_Jv_JNIEnv *);
_Jv_JNIEnv *_Jv_GetJNIEnvNewFrameWithLoader (::java::lang::ClassLoader *);
Graydon Hoare committed
633

634
struct _Jv_JavaVM;
635
_Jv_JavaVM *_Jv_GetJavaVM (); 
636

637
/* Get a JVMTI environment */
638 639 640
struct _Jv_JVMTIEnv;
_Jv_JVMTIEnv *_Jv_GetJVMTIEnv (void);

641 642 643
/* Initialize JVMTI */
extern void _Jv_JVMTI_Init (void);

644 645 646 647 648 649 650 651
// Some verification functions from defineclass.cc.
bool _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig);
bool _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig);
bool _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length);
bool _Jv_VerifyClassName (_Jv_Utf8Const *name);
bool _Jv_VerifyIdentifier (_Jv_Utf8Const *);
bool _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2);

Tom Tromey committed
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667
struct _Jv_core_chain
{
  int name_length;
  const char *name;
  int data_length;
  const void *data;

  struct _Jv_core_chain *next;
};

// This is called when new core data is loaded.
extern void (*_Jv_RegisterCoreHook) (_Jv_core_chain *);

_Jv_core_chain *_Jv_FindCore (_Jv_core_chain *node, jstring name);
void _Jv_FreeCoreChain (_Jv_core_chain *chain);

Anthony Green committed
668
#ifdef ENABLE_JVMPI
Tom Tromey committed
669

Anthony Green committed
670 671 672 673 674 675 676
#include "jvmpi.h"

extern void (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (JVMPI_Event *event);
extern void (*_Jv_JVMPI_Notify_THREAD_START) (JVMPI_Event *event);
extern void (*_Jv_JVMPI_Notify_THREAD_END) (JVMPI_Event *event);
#endif

677 678 679
/* FIXME: this should really be defined in some more generic place */
#define ROUND(V, A) (((((unsigned) (V))-1) | ((A)-1))+1)

680 681
extern void _Jv_RegisterBootstrapPackages ();

682
#define FLAG_BINARYCOMPAT_ABI (1<<31)  /* Class is built with the BC-ABI. */
683

684 685 686
#define FLAG_BOOTSTRAP_LOADER (1<<30)  /* Used when defining a class that 
					  should be loaded by the bootstrap
					  loader.  */
687

688 689 690 691 692 693 694 695
// These are used to find ABI versions we recognize.
#define GCJ_CXX_ABI_VERSION (__GNUC__ * 100000 + __GNUC_MINOR__ * 1000)

// This is the old-style BC version ID used by GCJ 4.0.0.
#define OLD_GCJ_40_BC_ABI_VERSION (4 * 10000 + 0 * 10 + 5)

// New style version IDs used by GCJ 4.0.1 and later.
#define GCJ_40_BC_ABI_VERSION (4 * 100000 + 0 * 1000)
696

697 698
void _Jv_CheckABIVersion (unsigned long value);

699 700 701 702

inline bool
_Jv_ClassForBootstrapLoader (unsigned long value)
{
703
  return (value & FLAG_BOOTSTRAP_LOADER);
704 705
}

706 707 708 709 710 711 712 713 714
// It makes the source cleaner if we simply always define this
// function.  If the interpreter is not built, it will never return
// 'true'.
extern inline jboolean
_Jv_IsInterpretedClass (jclass c)
{
  return (c->accflags & java::lang::reflect::Modifier::INTERPRETED) != 0;
}

715 716 717 718 719 720 721 722 723
// Return true if the class was compiled with the BC ABI.
extern inline jboolean
_Jv_IsBinaryCompatibilityABI (jclass c)
{
  // There isn't really a better test for the ABI type at this point,
  // that will work once the class has been registered.
  return c->otable_syms || c->atable_syms || c->itable_syms;
}

724 725 726 727 728 729 730 731 732 733
// Returns whether the given class does not really exists (ie. we have no
// bytecode) but still allows us to do some very conservative actions.
// E.g. throwing a NoClassDefFoundError with the name of the missing
// class.
extern inline jboolean
_Jv_IsPhantomClass (jclass c)
{
  return c->state == JV_STATE_PHANTOM;
}

734 735 736
// A helper function defined in prims.cc.
char* _Jv_PrependVersionedLibdir (char* libpath);

737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800

// An enum for use with JvSetThreadState.  We use a C++ enum rather
// than the Java enum to avoid problems with class initialization
// during VM bootstrap.
typedef enum
{
  JV_BLOCKED,
  JV_NEW,
  JV_RUNNABLE,
  JV_TERMINATED,
  JV_TIMED_WAITING,
  JV_WAITING
} JvThreadState;

// Temporarily set the thread's state.
class JvSetThreadState
{
private:
  ::java::lang::Thread *thread;
  jint saved;

public:

  // Note that 'cthread' could be NULL -- during VM startup there may
  // not be a Thread available.
  JvSetThreadState(::java::lang::Thread *cthread, JvThreadState nstate)
    : thread (cthread),
      saved (cthread ? cthread->state : (jint)JV_NEW)
  {
    if (thread)
      thread->state = nstate;
  }

  ~JvSetThreadState()
  {
    if (thread)
      thread->state = saved;
  }
};

// This structure is used to represent all the data the native side
// needs.  An object of this type is assigned to the `data' member of
// the Thread class.
struct natThread
{
  // A thread is either alive, dead, or being sent a signal; if it is
  // being sent a signal, it is also alive.  Thus, if you want to know
  // if a thread is alive, it is sufficient to test alive_status !=
  // THREAD_DEAD.
  volatile obj_addr_t alive_flag;

  // These are used to interrupt sleep and join calls.  We can share a
  // condition variable here since it only ever gets notified when the thread
  // exits.
  _Jv_Mutex_t join_mutex;
  _Jv_ConditionVariable_t join_cond;

  // These are used by Unsafe.park() and Unsafe.unpark().
  ParkHelper park_helper;

  // This is private data for the thread system layer.
  _Jv_Thread_t *thread;

  // Each thread has its own JNI object.
801
  _Jv_JNIEnv *jni_env;
802 803
};

Tom Tromey committed
804
#endif /* __JAVA_JVM_H__ */