OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [prims.cc] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
// prims.cc - Code for core of runtime environment.
2
 
3
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006  Free Software Foundation
4
 
5
   This file is part of libgcj.
6
 
7
This software is copyrighted work licensed under the terms of the
8
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9
details.  */
10
 
11
#include <config.h>
12
#include <platform.h>
13
 
14
#include <stdlib.h>
15
#include <stdarg.h>
16
#include <stdio.h>
17
#include <string.h>
18
#include <signal.h>
19
 
20
#ifdef HAVE_UNISTD_H
21
#include <unistd.h>
22
#endif
23
 
24
#include <gcj/cni.h>
25
#include <jvm.h>
26
#include <java-signal.h>
27
#include <java-threads.h>
28
#include <java-interp.h>
29
 
30
#ifdef ENABLE_JVMPI
31
#include <jvmpi.h>
32
#include <java/lang/ThreadGroup.h>
33
#endif
34
 
35
#ifndef DISABLE_GETENV_PROPERTIES
36
#include <ctype.h>
37
#include <java-props.h>
38
#define PROCESS_GCJ_PROPERTIES process_gcj_properties()
39
#else
40
#define PROCESS_GCJ_PROPERTIES
41
#endif // DISABLE_GETENV_PROPERTIES
42
 
43
#include <java/lang/Class.h>
44
#include <java/lang/ClassLoader.h>
45
#include <java/lang/Runtime.h>
46
#include <java/lang/String.h>
47
#include <java/lang/Thread.h>
48
#include <java/lang/ThreadGroup.h>
49
#include <java/lang/ArrayIndexOutOfBoundsException.h>
50
#include <java/lang/ArithmeticException.h>
51
#include <java/lang/ClassFormatError.h>
52
#include <java/lang/InternalError.h>
53
#include <java/lang/NegativeArraySizeException.h>
54
#include <java/lang/NullPointerException.h>
55
#include <java/lang/OutOfMemoryError.h>
56
#include <java/lang/System.h>
57
#include <java/lang/VMThrowable.h>
58
#include <java/lang/VMClassLoader.h>
59
#include <java/lang/reflect/Modifier.h>
60
#include <java/io/PrintStream.h>
61
#include <java/lang/UnsatisfiedLinkError.h>
62
#include <java/lang/VirtualMachineError.h>
63
#include <gnu/gcj/runtime/ExtensionClassLoader.h>
64
#include <gnu/gcj/runtime/FinalizerThread.h>
65
#include <execution.h>
66
#include <gnu/java/lang/MainThread.h>
67
 
68
#ifdef USE_LTDL
69
#include <ltdl.h>
70
#endif
71
 
72
// Execution engine for compiled code.
73
_Jv_CompiledEngine _Jv_soleCompiledEngine;
74
 
75
// We allocate a single OutOfMemoryError exception which we keep
76
// around for use if we run out of memory.
77
static java::lang::OutOfMemoryError *no_memory;
78
 
79
// Number of bytes in largest array object we create.  This could be
80
// increased to the largest size_t value, so long as the appropriate
81
// functions are changed to take a size_t argument instead of jint.
82
#define MAX_OBJECT_SIZE ((1<<31) - 1)
83
 
84
// Properties set at compile time.
85
const char **_Jv_Compiler_Properties = NULL;
86
int _Jv_Properties_Count = 0;
87
 
88
#ifndef DISABLE_GETENV_PROPERTIES
89
// Property key/value pairs.
90
property_pair *_Jv_Environment_Properties;
91
#endif
92
 
93
// Stash the argv pointer to benefit native libraries that need it.
94
const char **_Jv_argv;
95
int _Jv_argc;
96
 
97
// Argument support.
98
int
99
_Jv_GetNbArgs (void)
100
{
101
  // _Jv_argc is 0 if not explicitly initialized.
102
  return _Jv_argc;
103
}
104
 
105
const char *
106
_Jv_GetSafeArg (int index)
107
{
108
  if (index >=0 && index < _Jv_GetNbArgs ())
109
    return _Jv_argv[index];
110
  else
111
    return "";
112
}
113
 
114
void
115
_Jv_SetArgs (int argc, const char **argv)
116
{
117
  _Jv_argc = argc;
118
  _Jv_argv = argv;
119
}
120
 
121
#ifdef ENABLE_JVMPI
122
// Pointer to JVMPI notification functions.
123
void (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (JVMPI_Event *event);
124
void (*_Jv_JVMPI_Notify_THREAD_START) (JVMPI_Event *event);
125
void (*_Jv_JVMPI_Notify_THREAD_END) (JVMPI_Event *event);
126
#endif
127
 
128
 
129
#if defined (HANDLE_SEGV) || defined(HANDLE_FPE)
130
/* Unblock a signal.  Unless we do this, the signal may only be sent
131
   once.  */
132
static void
133
unblock_signal (int signum __attribute__ ((__unused__)))
134
{
135
#ifdef _POSIX_VERSION
136
  sigset_t sigs;
137
 
138
  sigemptyset (&sigs);
139
  sigaddset (&sigs, signum);
140
  sigprocmask (SIG_UNBLOCK, &sigs, NULL);
141
#endif
142
}
143
#endif
144
 
145
#ifdef HANDLE_SEGV
146
SIGNAL_HANDLER (catch_segv)
147
{
148
  unblock_signal (SIGSEGV);
149
  MAKE_THROW_FRAME (nullp);
150
  java::lang::NullPointerException *nullp
151
    = new java::lang::NullPointerException;
152
  throw nullp;
153
}
154
#endif
155
 
156
#ifdef HANDLE_FPE
157
SIGNAL_HANDLER (catch_fpe)
158
{
159
  unblock_signal (SIGFPE);
160
#ifdef HANDLE_DIVIDE_OVERFLOW
161
  HANDLE_DIVIDE_OVERFLOW;
162
#else
163
  MAKE_THROW_FRAME (arithexception);
164
#endif
165
  java::lang::ArithmeticException *arithexception
166
    = new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero"));
167
  throw arithexception;
168
}
169
#endif
170
 
171
 
172
 
173
jboolean
174
_Jv_equalUtf8Consts (const Utf8Const* a, const Utf8Const *b)
175
{
176
  int len;
177
  const _Jv_ushort *aptr, *bptr;
178
  if (a == b)
179
    return true;
180
  if (a->hash != b->hash)
181
    return false;
182
  len = a->length;
183
  if (b->length != len)
184
    return false;
185
  aptr = (const _Jv_ushort *)a->data;
186
  bptr = (const _Jv_ushort *)b->data;
187
  len = (len + 1) >> 1;
188
  while (--len >= 0)
189
    if (*aptr++ != *bptr++)
190
      return false;
191
  return true;
192
}
193
 
194
/* True iff A is equal to STR.
195
   HASH is STR->hashCode().
196
*/
197
 
198
jboolean
199
_Jv_equal (Utf8Const* a, jstring str, jint hash)
200
{
201
  if (a->hash != (_Jv_ushort) hash)
202
    return false;
203
  jint len = str->length();
204
  jint i = 0;
205
  jchar *sptr = _Jv_GetStringChars (str);
206
  unsigned char* ptr = (unsigned char*) a->data;
207
  unsigned char* limit = ptr + a->length;
208
  for (;; i++, sptr++)
209
    {
210
      int ch = UTF8_GET (ptr, limit);
211
      if (i == len)
212
        return ch < 0;
213
      if (ch != *sptr)
214
        return false;
215
    }
216
  return true;
217
}
218
 
219
/* Like _Jv_equal, but stop after N characters.  */
220
jboolean
221
_Jv_equaln (Utf8Const *a, jstring str, jint n)
222
{
223
  jint len = str->length();
224
  jint i = 0;
225
  jchar *sptr = _Jv_GetStringChars (str);
226
  unsigned char* ptr = (unsigned char*) a->data;
227
  unsigned char* limit = ptr + a->length;
228
  for (; n-- > 0; i++, sptr++)
229
    {
230
      int ch = UTF8_GET (ptr, limit);
231
      if (i == len)
232
        return ch < 0;
233
      if (ch != *sptr)
234
        return false;
235
    }
236
  return true;
237
}
238
 
239
/* Count the number of Unicode chars encoded in a given Ut8 string. */
240
int
241
_Jv_strLengthUtf8(char* str, int len)
242
{
243
  unsigned char* ptr;
244
  unsigned char* limit;
245
  int str_length;
246
 
247
  ptr = (unsigned char*) str;
248
  limit = ptr + len;
249
  str_length = 0;
250
  for (; ptr < limit; str_length++)
251
    {
252
      if (UTF8_GET (ptr, limit) < 0)
253
        return (-1);
254
    }
255
  return (str_length);
256
}
257
 
258
/* Calculate a hash value for a string encoded in Utf8 format.
259
 * This returns the same hash value as specified or java.lang.String.hashCode.
260
 */
261
jint
262
_Jv_hashUtf8String (char* str, int len)
263
{
264
  unsigned char* ptr = (unsigned char*) str;
265
  unsigned char* limit = ptr + len;
266
  jint hash = 0;
267
 
268
  for (; ptr < limit;)
269
    {
270
      int ch = UTF8_GET (ptr, limit);
271
      /* Updated specification from
272
         http://www.javasoft.com/docs/books/jls/clarify.html. */
273
      hash = (31 * hash) + ch;
274
    }
275
  return hash;
276
}
277
 
278
void
279
_Jv_Utf8Const::init(char *s, int len)
280
{
281
  ::memcpy (data, s, len);
282
  data[len] = 0;
283
  length = len;
284
  hash = _Jv_hashUtf8String (s, len) & 0xFFFF;
285
}
286
 
287
_Jv_Utf8Const *
288
_Jv_makeUtf8Const (char* s, int len)
289
{
290
  if (len < 0)
291
    len = strlen (s);
292
  Utf8Const* m
293
    = (Utf8Const*) _Jv_AllocBytes (_Jv_Utf8Const::space_needed(s, len));
294
  m->init(s, len);
295
  return m;
296
}
297
 
298
_Jv_Utf8Const *
299
_Jv_makeUtf8Const (jstring string)
300
{
301
  jint hash = string->hashCode ();
302
  jint len = _Jv_GetStringUTFLength (string);
303
 
304
  Utf8Const* m = (Utf8Const*)
305
    _Jv_AllocBytes (sizeof(Utf8Const) + len + 1);
306
 
307
  m->hash = hash;
308
  m->length = len;
309
 
310
  _Jv_GetStringUTFRegion (string, 0, string->length (), m->data);
311
  m->data[len] = 0;
312
 
313
  return m;
314
}
315
 
316
 
317
 
318
#ifdef DEBUG
319
void
320
_Jv_Abort (const char *function, const char *file, int line,
321
           const char *message)
322
#else
323
void
324
_Jv_Abort (const char *, const char *, int, const char *message)
325
#endif
326
{
327
#ifdef DEBUG
328
  fprintf (stderr,
329
           "libgcj failure: %s\n   in function %s, file %s, line %d\n",
330
           message, function, file, line);
331
#else
332
  fprintf (stderr, "libgcj failure: %s\n", message);
333
#endif
334
  abort ();
335
}
336
 
337
static void
338
fail_on_finalization (jobject)
339
{
340
  JvFail ("object was finalized");
341
}
342
 
343
void
344
_Jv_GCWatch (jobject obj)
345
{
346
  _Jv_RegisterFinalizer (obj, fail_on_finalization);
347
}
348
 
349
void
350
_Jv_ThrowBadArrayIndex(jint bad_index)
351
{
352
  throw new java::lang::ArrayIndexOutOfBoundsException
353
    (java::lang::String::valueOf (bad_index));
354
}
355
 
356
void
357
_Jv_ThrowNullPointerException ()
358
{
359
  throw new java::lang::NullPointerException;
360
}
361
 
362
// Resolve an entry in the constant pool and return the target
363
// address.
364
void *
365
_Jv_ResolvePoolEntry (jclass this_class, jint index)
366
{
367
  _Jv_Constants *pool = &this_class->constants;
368
 
369
  if ((pool->tags[index] & JV_CONSTANT_ResolvedFlag) != 0)
370
    return pool->data[index].field->u.addr;
371
 
372
  JvSynchronize sync (this_class);
373
  return (_Jv_Linker::resolve_pool_entry (this_class, index))
374
    .field->u.addr;
375
}
376
 
377
 
378
// Explicitly throw a no memory exception.
379
// The collector calls this when it encounters an out-of-memory condition.
380
void _Jv_ThrowNoMemory()
381
{
382
  throw no_memory;
383
}
384
 
385
#ifdef ENABLE_JVMPI
386
# define JVMPI_NOTIFY_ALLOC(klass,size,obj) \
387
    if (__builtin_expect (_Jv_JVMPI_Notify_OBJECT_ALLOC != 0, false)) \
388
      jvmpi_notify_alloc(klass,size,obj);
389
static void
390
jvmpi_notify_alloc(jclass klass, jint size, jobject obj)
391
{
392
  // Service JVMPI allocation request.
393
  JVMPI_Event event;
394
 
395
  event.event_type = JVMPI_EVENT_OBJECT_ALLOC;
396
  event.env_id = NULL;
397
  event.u.obj_alloc.arena_id = 0;
398
  event.u.obj_alloc.class_id = (jobjectID) klass;
399
  event.u.obj_alloc.is_array = 0;
400
  event.u.obj_alloc.size = size;
401
  event.u.obj_alloc.obj_id = (jobjectID) obj;
402
 
403
  // FIXME:  This doesn't look right for the Boehm GC.  A GC may
404
  // already be in progress.  _Jv_DisableGC () doesn't wait for it.
405
  // More importantly, I don't see the need for disabling GC, since we
406
  // blatantly have a pointer to obj on our stack, ensuring that the
407
  // object can't be collected.  Even for a nonconservative collector,
408
  // it appears to me that this must be true, since we are about to
409
  // return obj. Isn't this whole approach way too intrusive for
410
  // a useful profiling interface?                      - HB
411
  _Jv_DisableGC ();
412
  (*_Jv_JVMPI_Notify_OBJECT_ALLOC) (&event);
413
  _Jv_EnableGC ();
414
}
415
#else /* !ENABLE_JVMPI */
416
# define JVMPI_NOTIFY_ALLOC(klass,size,obj) /* do nothing */
417
#endif
418
 
419
// Allocate a new object of class KLASS.
420
// First a version that assumes that we have no finalizer, and that
421
// the class is already initialized.
422
// If we know that JVMPI is disabled, this can be replaced by a direct call
423
// to the allocator for the appropriate GC.
424
jobject
425
_Jv_AllocObjectNoInitNoFinalizer (jclass klass)
426
{
427
  jint size = klass->size ();
428
  jobject obj = (jobject) _Jv_AllocObj (size, klass);
429
  JVMPI_NOTIFY_ALLOC (klass, size, obj);
430
  return obj;
431
}
432
 
433
// And now a version that initializes if necessary.
434
jobject
435
_Jv_AllocObjectNoFinalizer (jclass klass)
436
{
437
  _Jv_InitClass (klass);
438
  jint size = klass->size ();
439
  jobject obj = (jobject) _Jv_AllocObj (size, klass);
440
  JVMPI_NOTIFY_ALLOC (klass, size, obj);
441
  return obj;
442
}
443
 
444
// And now the general version that registers a finalizer if necessary.
445
jobject
446
_Jv_AllocObject (jclass klass)
447
{
448
  jobject obj = _Jv_AllocObjectNoFinalizer (klass);
449
 
450
  // We assume that the compiler only generates calls to this routine
451
  // if there really is an interesting finalizer.
452
  // Unfortunately, we still have to the dynamic test, since there may
453
  // be cni calls to this routine.
454
  // Note that on IA64 get_finalizer() returns the starting address of the
455
  // function, not a function pointer.  Thus this still works.
456
  if (klass->vtable->get_finalizer ()
457
      != java::lang::Object::class$.vtable->get_finalizer ())
458
    _Jv_RegisterFinalizer (obj, _Jv_FinalizeObject);
459
  return obj;
460
}
461
 
462
// Allocate a String, including variable length storage.
463
jstring
464
_Jv_AllocString(jsize len)
465
{
466
  using namespace java::lang;
467
 
468
  jsize sz = sizeof(java::lang::String) + len * sizeof(jchar);
469
 
470
  // We assert that for strings allocated this way, the data field
471
  // will always point to the object itself.  Thus there is no reason
472
  // for the garbage collector to scan any of it.
473
  // Furthermore, we're about to overwrite the string data, so
474
  // initialization of the object is not an issue.
475
 
476
  // String needs no initialization, and there is no finalizer, so
477
  // we can go directly to the collector's allocator interface.
478
  jstring obj = (jstring) _Jv_AllocPtrFreeObj(sz, &String::class$);
479
 
480
  obj->data = obj;
481
  obj->boffset = sizeof(java::lang::String);
482
  obj->count = len;
483
  obj->cachedHashCode = 0;
484
 
485
  JVMPI_NOTIFY_ALLOC (&String::class$, sz, obj);
486
 
487
  return obj;
488
}
489
 
490
// A version of the above that assumes the object contains no pointers,
491
// and requires no finalization.  This can't happen if we need pointers
492
// to locks.
493
#ifdef JV_HASH_SYNCHRONIZATION
494
jobject
495
_Jv_AllocPtrFreeObject (jclass klass)
496
{
497
  _Jv_InitClass (klass);
498
  jint size = klass->size ();
499
 
500
  jobject obj = (jobject) _Jv_AllocPtrFreeObj (size, klass);
501
 
502
  JVMPI_NOTIFY_ALLOC (klass, size, obj);
503
 
504
  return obj;
505
}
506
#endif /* JV_HASH_SYNCHRONIZATION */
507
 
508
 
509
// Allocate a new array of Java objects.  Each object is of type
510
// `elementClass'.  `init' is used to initialize each slot in the
511
// array.
512
jobjectArray
513
_Jv_NewObjectArray (jsize count, jclass elementClass, jobject init)
514
{
515
  if (__builtin_expect (count < 0, false))
516
    throw new java::lang::NegativeArraySizeException;
517
 
518
  JvAssert (! elementClass->isPrimitive ());
519
 
520
  // Ensure that elements pointer is properly aligned.
521
  jobjectArray obj = NULL;
522
  size_t size = (size_t) elements (obj);
523
  // Check for overflow.
524
  if (__builtin_expect ((size_t) count >
525
                        (MAX_OBJECT_SIZE - 1 - size) / sizeof (jobject), false))
526
    throw no_memory;
527
 
528
  size += count * sizeof (jobject);
529
 
530
  jclass klass = _Jv_GetArrayClass (elementClass,
531
                                    elementClass->getClassLoaderInternal());
532
 
533
  obj = (jobjectArray) _Jv_AllocArray (size, klass);
534
  // Cast away const.
535
  jsize *lp = const_cast<jsize *> (&obj->length);
536
  *lp = count;
537
  // We know the allocator returns zeroed memory.  So don't bother
538
  // zeroing it again.
539
  if (init)
540
    {
541
      jobject *ptr = elements(obj);
542
      while (--count >= 0)
543
        *ptr++ = init;
544
    }
545
  return obj;
546
}
547
 
548
// Allocate a new array of primitives.  ELTYPE is the type of the
549
// element, COUNT is the size of the array.
550
jobject
551
_Jv_NewPrimArray (jclass eltype, jint count)
552
{
553
  int elsize = eltype->size();
554
  if (__builtin_expect (count < 0, false))
555
    throw new java::lang::NegativeArraySizeException;
556
 
557
  JvAssert (eltype->isPrimitive ());
558
  jobject dummy = NULL;
559
  size_t size = (size_t) _Jv_GetArrayElementFromElementType (dummy, eltype);
560
 
561
  // Check for overflow.
562
  if (__builtin_expect ((size_t) count >
563
                        (MAX_OBJECT_SIZE - size) / elsize, false))
564
    throw no_memory;
565
 
566
  jclass klass = _Jv_GetArrayClass (eltype, 0);
567
 
568
# ifdef JV_HASH_SYNCHRONIZATION
569
  // Since the vtable is always statically allocated,
570
  // these are completely pointerfree!  Make sure the GC doesn't touch them.
571
  __JArray *arr =
572
    (__JArray*) _Jv_AllocPtrFreeObj (size + elsize * count, klass);
573
  memset((char *)arr + size, 0, elsize * count);
574
# else
575
  __JArray *arr = (__JArray*) _Jv_AllocObj (size + elsize * count, klass);
576
  // Note that we assume we are given zeroed memory by the allocator.
577
# endif
578
  // Cast away const.
579
  jsize *lp = const_cast<jsize *> (&arr->length);
580
  *lp = count;
581
 
582
  return arr;
583
}
584
 
585
jobject
586
_Jv_NewArray (jint type, jint size)
587
{
588
  switch (type)
589
    {
590
      case  4:  return JvNewBooleanArray (size);
591
      case  5:  return JvNewCharArray (size);
592
      case  6:  return JvNewFloatArray (size);
593
      case  7:  return JvNewDoubleArray (size);
594
      case  8:  return JvNewByteArray (size);
595
      case  9:  return JvNewShortArray (size);
596
      case 10:  return JvNewIntArray (size);
597
      case 11:  return JvNewLongArray (size);
598
    }
599
  throw new java::lang::InternalError
600
    (JvNewStringLatin1 ("invalid type code in _Jv_NewArray"));
601
}
602
 
603
// Allocate a possibly multi-dimensional array but don't check that
604
// any array length is <0.
605
static jobject
606
_Jv_NewMultiArrayUnchecked (jclass type, jint dimensions, jint *sizes)
607
{
608
  JvAssert (type->isArray());
609
  jclass element_type = type->getComponentType();
610
  jobject result;
611
  if (element_type->isPrimitive())
612
    result = _Jv_NewPrimArray (element_type, sizes[0]);
613
  else
614
    result = _Jv_NewObjectArray (sizes[0], element_type, NULL);
615
 
616
  if (dimensions > 1)
617
    {
618
      JvAssert (! element_type->isPrimitive());
619
      JvAssert (element_type->isArray());
620
      jobject *contents = elements ((jobjectArray) result);
621
      for (int i = 0; i < sizes[0]; ++i)
622
        contents[i] = _Jv_NewMultiArrayUnchecked (element_type, dimensions - 1,
623
                                                  sizes + 1);
624
    }
625
 
626
  return result;
627
}
628
 
629
jobject
630
_Jv_NewMultiArray (jclass type, jint dimensions, jint *sizes)
631
{
632
  for (int i = 0; i < dimensions; ++i)
633
    if (sizes[i] < 0)
634
      throw new java::lang::NegativeArraySizeException;
635
 
636
  return _Jv_NewMultiArrayUnchecked (type, dimensions, sizes);
637
}
638
 
639
jobject
640
_Jv_NewMultiArray (jclass array_type, jint dimensions, ...)
641
{
642
  va_list args;
643
  jint sizes[dimensions];
644
  va_start (args, dimensions);
645
  for (int i = 0; i < dimensions; ++i)
646
    {
647
      jint size = va_arg (args, jint);
648
      if (size < 0)
649
        throw new java::lang::NegativeArraySizeException;
650
      sizes[i] = size;
651
    }
652
  va_end (args);
653
 
654
  return _Jv_NewMultiArrayUnchecked (array_type, dimensions, sizes);
655
}
656
 
657
 
658
 
659
// Ensure 8-byte alignment, for hash synchronization.
660
#define DECLARE_PRIM_TYPE(NAME)                 \
661
  java::lang::Class _Jv_##NAME##Class __attribute__ ((aligned (8)));
662
 
663
DECLARE_PRIM_TYPE(byte)
664
DECLARE_PRIM_TYPE(short)
665
DECLARE_PRIM_TYPE(int)
666
DECLARE_PRIM_TYPE(long)
667
DECLARE_PRIM_TYPE(boolean)
668
DECLARE_PRIM_TYPE(char)
669
DECLARE_PRIM_TYPE(float)
670
DECLARE_PRIM_TYPE(double)
671
DECLARE_PRIM_TYPE(void)
672
 
673
void
674
_Jv_InitPrimClass (jclass cl, char *cname, char sig, int len)
675
{
676
  using namespace java::lang::reflect;
677
 
678
  // We must set the vtable for the class; the Java constructor
679
  // doesn't do this.
680
  (*(_Jv_VTable **) cl) = java::lang::Class::class$.vtable;
681
 
682
  // Initialize the fields we care about.  We do this in the same
683
  // order they are declared in Class.h.
684
  cl->name = _Jv_makeUtf8Const ((char *) cname, -1);
685
  cl->accflags = Modifier::PUBLIC | Modifier::FINAL | Modifier::ABSTRACT;
686
  cl->method_count = sig;
687
  cl->size_in_bytes = len;
688
  cl->vtable = JV_PRIMITIVE_VTABLE;
689
  cl->state = JV_STATE_DONE;
690
  cl->depth = -1;
691
}
692
 
693
jclass
694
_Jv_FindClassFromSignature (char *sig, java::lang::ClassLoader *loader,
695
                            char **endp)
696
{
697
  // First count arrays.
698
  int array_count = 0;
699
  while (*sig == '[')
700
    {
701
      ++sig;
702
      ++array_count;
703
    }
704
 
705
  jclass result = NULL;
706
  switch (*sig)
707
    {
708
    case 'B':
709
      result = JvPrimClass (byte);
710
      break;
711
    case 'S':
712
      result = JvPrimClass (short);
713
      break;
714
    case 'I':
715
      result = JvPrimClass (int);
716
      break;
717
    case 'J':
718
      result = JvPrimClass (long);
719
      break;
720
    case 'Z':
721
      result = JvPrimClass (boolean);
722
      break;
723
    case 'C':
724
      result = JvPrimClass (char);
725
      break;
726
    case 'F':
727
      result = JvPrimClass (float);
728
      break;
729
    case 'D':
730
      result = JvPrimClass (double);
731
      break;
732
    case 'V':
733
      result = JvPrimClass (void);
734
      break;
735
    case 'L':
736
      {
737
        char *save = ++sig;
738
        while (*sig && *sig != ';')
739
          ++sig;
740
        // Do nothing if signature appears to be malformed.
741
        if (*sig == ';')
742
          {
743
            _Jv_Utf8Const *name = _Jv_makeUtf8Const (save, sig - save);
744
            result = _Jv_FindClass (name, loader);
745
          }
746
        break;
747
      }
748
    default:
749
      // Do nothing -- bad signature.
750
      break;
751
    }
752
 
753
  if (endp)
754
    {
755
      // Not really the "end", but the last valid character that we
756
      // looked at.
757
      *endp = sig;
758
    }
759
 
760
  if (! result)
761
    return NULL;
762
 
763
  // Find arrays.
764
  while (array_count-- > 0)
765
    result = _Jv_GetArrayClass (result, loader);
766
  return result;
767
}
768
 
769
 
770
 
771
JArray<jstring> *
772
JvConvertArgv (int argc, const char **argv)
773
{
774
  if (argc < 0)
775
    argc = 0;
776
  jobjectArray ar = JvNewObjectArray(argc, &java::lang::String::class$, NULL);
777
  jobject *ptr = elements(ar);
778
  jbyteArray bytes = NULL;
779
  for (int i = 0;  i < argc;  i++)
780
    {
781
      const char *arg = argv[i];
782
      int len = strlen (arg);
783
      if (bytes == NULL || bytes->length < len)
784
        bytes = JvNewByteArray (len);
785
      jbyte *bytePtr = elements (bytes);
786
      // We assume jbyte == char.
787
      memcpy (bytePtr, arg, len);
788
 
789
      // Now convert using the default encoding.
790
      *ptr++ = new java::lang::String (bytes, 0, len);
791
    }
792
  return (JArray<jstring>*) ar;
793
}
794
 
795
// FIXME: These variables are static so that they will be
796
// automatically scanned by the Boehm collector.  This is needed
797
// because with qthreads the collector won't scan the initial stack --
798
// it will only scan the qthreads stacks.
799
 
800
// Command line arguments.
801
static JArray<jstring> *arg_vec;
802
 
803
// The primary thread.
804
static java::lang::Thread *main_thread;
805
 
806
#ifndef DISABLE_GETENV_PROPERTIES
807
 
808
static char *
809
next_property_key (char *s, size_t *length)
810
{
811
  size_t l = 0;
812
 
813
  JvAssert (s);
814
 
815
  // Skip over whitespace
816
  while (isspace (*s))
817
    s++;
818
 
819
  // If we've reached the end, return NULL.  Also return NULL if for
820
  // some reason we've come across a malformed property string.
821
  if (*s == 0
822
      || *s == ':'
823
      || *s == '=')
824
    return NULL;
825
 
826
  // Determine the length of the property key.
827
  while (s[l] != 0
828
         && ! isspace (s[l])
829
         && s[l] != ':'
830
         && s[l] != '=')
831
    {
832
      if (s[l] == '\\'
833
          && s[l+1] != 0)
834
        l++;
835
      l++;
836
    }
837
 
838
  *length = l;
839
 
840
  return s;
841
}
842
 
843
static char *
844
next_property_value (char *s, size_t *length)
845
{
846
  size_t l = 0;
847
 
848
  JvAssert (s);
849
 
850
  while (isspace (*s))
851
    s++;
852
 
853
  if (*s == ':'
854
      || *s == '=')
855
    s++;
856
 
857
  while (isspace (*s))
858
    s++;
859
 
860
  // Determine the length of the property value.
861
  while (s[l] != 0
862
         && ! isspace (s[l])
863
         && s[l] != ':'
864
         && s[l] != '=')
865
    {
866
      if (s[l] == '\\'
867
          && s[l+1] != 0)
868
        l += 2;
869
      else
870
        l++;
871
    }
872
 
873
  *length = l;
874
 
875
  return s;
876
}
877
 
878
static void
879
process_gcj_properties ()
880
{
881
  char *props = getenv("GCJ_PROPERTIES");
882
 
883
  if (NULL == props)
884
    return;
885
 
886
  // Later on we will write \0s into this string.  It is simplest to
887
  // just duplicate it here.
888
  props = strdup (props);
889
 
890
  char *p = props;
891
  size_t length;
892
  size_t property_count = 0;
893
 
894
  // Whip through props quickly in order to count the number of
895
  // property values.
896
  while (p && (p = next_property_key (p, &length)))
897
    {
898
      // Skip to the end of the key
899
      p += length;
900
 
901
      p = next_property_value (p, &length);
902
      if (p)
903
        p += length;
904
 
905
      property_count++;
906
    }
907
 
908
  // Allocate an array of property value/key pairs.
909
  _Jv_Environment_Properties =
910
    (property_pair *) malloc (sizeof(property_pair)
911
                              * (property_count + 1));
912
 
913
  // Go through the properties again, initializing _Jv_Properties
914
  // along the way.
915
  p = props;
916
  property_count = 0;
917
  while (p && (p = next_property_key (p, &length)))
918
    {
919
      _Jv_Environment_Properties[property_count].key = p;
920
      _Jv_Environment_Properties[property_count].key_length = length;
921
 
922
      // Skip to the end of the key
923
      p += length;
924
 
925
      p = next_property_value (p, &length);
926
 
927
      _Jv_Environment_Properties[property_count].value = p;
928
      _Jv_Environment_Properties[property_count].value_length = length;
929
 
930
      if (p)
931
        p += length;
932
 
933
      property_count++;
934
    }
935
  memset ((void *) &_Jv_Environment_Properties[property_count],
936
          0, sizeof (property_pair));
937
 
938
  // Null terminate the strings.
939
  for (property_pair *prop = &_Jv_Environment_Properties[0];
940
       prop->key != NULL;
941
       prop++)
942
    {
943
      prop->key[prop->key_length] = 0;
944
      prop->value[prop->value_length] = 0;
945
    }
946
}
947
#endif // DISABLE_GETENV_PROPERTIES
948
 
949
namespace gcj
950
{
951
  _Jv_Utf8Const *void_signature;
952
  _Jv_Utf8Const *clinit_name;
953
  _Jv_Utf8Const *init_name;
954
  _Jv_Utf8Const *finit_name;
955
 
956
  bool runtimeInitialized = false;
957
 
958
  // When true, print debugging information about class loading.
959
  bool verbose_class_flag;
960
 
961
  // When true, enable the bytecode verifier and BC-ABI type verification. 
962
  bool verifyClasses = true;
963
 
964
  // Thread stack size specified by the -Xss runtime argument.
965
  size_t stack_size = 0;
966
}
967
 
968
// We accept all non-standard options accepted by Sun's java command,
969
// for compatibility with existing application launch scripts.
970
static jint
971
parse_x_arg (char* option_string)
972
{
973
  if (strlen (option_string) <= 0)
974
    return -1;
975
 
976
  if (! strcmp (option_string, "int"))
977
    {
978
      // FIXME: this should cause the vm to never load shared objects
979
    }
980
  else if (! strcmp (option_string, "mixed"))
981
    {
982
      // FIXME: allow interpreted and native code
983
    }
984
  else if (! strcmp (option_string, "batch"))
985
    {
986
      // FIXME: disable background JIT'ing
987
    }
988
  else if (! strcmp (option_string, "debug"))
989
    {
990
      // FIXME: add JDWP/JVMDI support
991
    }
992
  else if (! strncmp (option_string, "bootclasspath:", 14))
993
    {
994
      // FIXME: add a parse_bootclasspath_arg function
995
    }
996
  else if (! strncmp (option_string, "bootclasspath/a:", 16))
997
    {
998
    }
999
  else if (! strncmp (option_string, "bootclasspath/p:", 16))
1000
    {
1001
    }
1002
  else if (! strcmp (option_string, "check:jni"))
1003
    {
1004
      // FIXME: enable strict JNI checking
1005
    }
1006
  else if (! strcmp (option_string, "future"))
1007
    {
1008
      // FIXME: enable strict class file format checks
1009
    }
1010
  else if (! strcmp (option_string, "noclassgc"))
1011
    {
1012
      // FIXME: disable garbage collection for classes
1013
    }
1014
  else if (! strcmp (option_string, "incgc"))
1015
    {
1016
      // FIXME: incremental garbage collection
1017
    }
1018
  else if (! strncmp (option_string, "loggc:", 6))
1019
    {
1020
      if (option_string[6] == '\0')
1021
        {
1022
          fprintf (stderr,
1023
                   "libgcj: filename argument expected for loggc option\n");
1024
          return -1;
1025
        }
1026
      // FIXME: set gc logging filename
1027
    }
1028
  else if (! strncmp (option_string, "ms", 2))
1029
    {
1030
      // FIXME: ignore this option until PR 20699 is fixed.
1031
      // _Jv_SetInitialHeapSize (option_string + 2);
1032
    }
1033
  else if (! strncmp (option_string, "mx", 2))
1034
    _Jv_SetMaximumHeapSize (option_string + 2);
1035
  else if (! strcmp (option_string, "prof"))
1036
    {
1037
      // FIXME: enable profiling of program running in vm
1038
    }
1039
  else if (! strncmp (option_string, "runhprof:", 9))
1040
    {
1041
      // FIXME: enable specific type of vm profiling.  add a
1042
      // parse_runhprof_arg function
1043
    }
1044
  else if (! strcmp (option_string, "rs"))
1045
    {
1046
      // FIXME: reduced system signal usage.  disable thread dumps,
1047
      // only terminate in response to user-initiated calls,
1048
      // e.g. System.exit()
1049
    }
1050
  else if (! strncmp (option_string, "ss", 2))
1051
    {
1052
      _Jv_SetStackSize (option_string + 2);
1053
    }
1054
  else if (! strcmp (option_string, "X:+UseAltSigs"))
1055
    {
1056
      // FIXME: use signals other than SIGUSR1 and SIGUSR2
1057
    }
1058
  else if (! strcmp (option_string, "share:off"))
1059
    {
1060
      // FIXME: don't share class data
1061
    }
1062
  else if (! strcmp (option_string, "share:auto"))
1063
    {
1064
      // FIXME: share class data where possible
1065
    }
1066
  else if (! strcmp (option_string, "share:on"))
1067
    {
1068
      // FIXME: fail if impossible to share class data
1069
    }
1070
 
1071
  return 0;
1072
}
1073
 
1074
static jint
1075
parse_verbose_args (char* option_string,
1076
                    bool ignore_unrecognized)
1077
{
1078
  size_t len = sizeof ("-verbose") - 1;
1079
 
1080
  if (strlen (option_string) < len)
1081
    return -1;
1082
 
1083
  if (option_string[len] == ':'
1084
      && option_string[len + 1] != '\0')
1085
    {
1086
      char* verbose_args = option_string + len + 1;
1087
 
1088
      do
1089
        {
1090
          if (! strncmp (verbose_args,
1091
                         "gc", sizeof ("gc") - 1))
1092
            {
1093
              if (verbose_args[sizeof ("gc") - 1] == '\0'
1094
                  || verbose_args[sizeof ("gc") - 1] == ',')
1095
                {
1096
                  // FIXME: we should add functions to boehm-gc that
1097
                  // toggle GC_print_stats, GC_PRINT_ADDRESS_MAP and
1098
                  // GC_print_back_height.
1099
                  verbose_args += sizeof ("gc") - 1;
1100
                }
1101
              else
1102
                {
1103
                verbose_arg_err:
1104
                  fprintf (stderr, "libgcj: unknown verbose option: %s\n",
1105
                           option_string);
1106
                  return -1;
1107
                }
1108
            }
1109
          else if (! strncmp (verbose_args,
1110
                              "class",
1111
                              sizeof ("class") - 1))
1112
            {
1113
              if (verbose_args[sizeof ("class") - 1] == '\0'
1114
                  || verbose_args[sizeof ("class") - 1] == ',')
1115
                {
1116
                  gcj::verbose_class_flag = true;
1117
                  verbose_args += sizeof ("class") - 1;
1118
                }
1119
              else
1120
                goto verbose_arg_err;
1121
            }
1122
          else if (! strncmp (verbose_args, "jni",
1123
                              sizeof ("jni") - 1))
1124
            {
1125
              if (verbose_args[sizeof ("jni") - 1] == '\0'
1126
                  || verbose_args[sizeof ("jni") - 1] == ',')
1127
                {
1128
                  // FIXME: enable JNI messages.
1129
                  verbose_args += sizeof ("jni") - 1;
1130
                }
1131
              else
1132
                goto verbose_arg_err;
1133
            }
1134
          else if (ignore_unrecognized
1135
                   && verbose_args[0] == 'X')
1136
            {
1137
              // ignore unrecognized non-standard verbose option
1138
              while (verbose_args[0] != '\0'
1139
                     && verbose_args[0] != ',')
1140
                verbose_args++;
1141
            }
1142
          else if (verbose_args[0] == ',')
1143
            {
1144
              verbose_args++;
1145
            }
1146
          else
1147
            goto verbose_arg_err;
1148
 
1149
          if (verbose_args[0] == ',')
1150
            verbose_args++;
1151
        }
1152
      while (verbose_args[0] != '\0');
1153
    }
1154
  else if (option_string[len] == 'g'
1155
           && option_string[len + 1] == 'c'
1156
           && option_string[len + 2] == '\0')
1157
    {
1158
      // FIXME: we should add functions to boehm-gc that
1159
      // toggle GC_print_stats, GC_PRINT_ADDRESS_MAP and
1160
      // GC_print_back_height.
1161
      return 0;
1162
    }
1163
  else if (option_string[len] == '\0')
1164
    {
1165
      gcj::verbose_class_flag = true;
1166
      return 0;
1167
    }
1168
  else
1169
    {
1170
      // unrecognized option beginning with -verbose
1171
      return -1;
1172
    }
1173
  return 0;
1174
}
1175
 
1176
static jint
1177
parse_init_args (JvVMInitArgs* vm_args)
1178
{
1179
  // if _Jv_Compiler_Properties is non-NULL then it needs to be
1180
  // re-allocated dynamically.
1181
  if (_Jv_Compiler_Properties)
1182
    {
1183
      const char** props = _Jv_Compiler_Properties;
1184
      _Jv_Compiler_Properties = NULL;
1185
 
1186
      for (int i = 0; props[i]; i++)
1187
        {
1188
          _Jv_Compiler_Properties = (const char**) _Jv_Realloc
1189
            (_Jv_Compiler_Properties,
1190
             (_Jv_Properties_Count + 1) * sizeof (const char*));
1191
          _Jv_Compiler_Properties[_Jv_Properties_Count++] = props[i];
1192
        }
1193
    }
1194
 
1195
  if (vm_args == NULL)
1196
    return 0;
1197
 
1198
  for (int i = 0; i < vm_args->nOptions; ++i)
1199
    {
1200
      char* option_string = vm_args->options[i].optionString;
1201
      if (! strcmp (option_string, "vfprintf")
1202
          || ! strcmp (option_string, "exit")
1203
          || ! strcmp (option_string, "abort"))
1204
        {
1205
          // FIXME: we are required to recognize these, but for
1206
          // now we don't handle them in any way.
1207
          continue;
1208
        }
1209
      else if (! strncmp (option_string,
1210
                          "-verbose", sizeof ("-verbose") - 1))
1211
        {
1212
          jint result = parse_verbose_args (option_string,
1213
                                            vm_args->ignoreUnrecognized);
1214
          if (result < 0)
1215
            return result;
1216
        }
1217
      else if (! strncmp (option_string, "-D", 2))
1218
        {
1219
          _Jv_Compiler_Properties = (const char**) _Jv_Realloc
1220
            (_Jv_Compiler_Properties,
1221
             (_Jv_Properties_Count + 1) * sizeof (char*));
1222
 
1223
          _Jv_Compiler_Properties[_Jv_Properties_Count++] =
1224
            strdup (option_string + 2);
1225
 
1226
          continue;
1227
        }
1228
      else if (vm_args->ignoreUnrecognized)
1229
        {
1230
          if (option_string[0] == '_')
1231
            parse_x_arg (option_string + 1);
1232
          else if (! strncmp (option_string, "-X", 2))
1233
            parse_x_arg (option_string + 2);
1234
          else
1235
            {
1236
            unknown_option:
1237
              fprintf (stderr, "libgcj: unknown option: %s\n", option_string);
1238
              return -1;
1239
            }
1240
        }
1241
      else
1242
        goto unknown_option;
1243
    }
1244
  return 0;
1245
}
1246
 
1247
jint
1248
_Jv_CreateJavaVM (JvVMInitArgs* vm_args)
1249
{
1250
  using namespace gcj;
1251
 
1252
  if (runtimeInitialized)
1253
    return -1;
1254
 
1255
  runtimeInitialized = true;
1256
 
1257
  jint result = parse_init_args (vm_args);
1258
  if (result < 0)
1259
    return -1;
1260
 
1261
  PROCESS_GCJ_PROPERTIES;
1262
 
1263
  /* Threads must be initialized before the GC, so that it inherits the
1264
     signal mask.  */
1265
  _Jv_InitThreads ();
1266
  _Jv_InitGC ();
1267
  _Jv_InitializeSyncMutex ();
1268
 
1269
#ifdef INTERPRETER
1270
  _Jv_InitInterpreter ();
1271
#endif  
1272
 
1273
#ifdef HANDLE_SEGV
1274
  INIT_SEGV;
1275
#endif
1276
 
1277
#ifdef HANDLE_FPE
1278
  INIT_FPE;
1279
#endif
1280
 
1281
  /* Initialize Utf8 constants declared in jvm.h. */
1282
  void_signature = _Jv_makeUtf8Const ("()V", 3);
1283
  clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
1284
  init_name = _Jv_makeUtf8Const ("<init>", 6);
1285
  finit_name = _Jv_makeUtf8Const ("finit$", 6);
1286
 
1287
  /* Initialize built-in classes to represent primitive TYPEs. */
1288
  _Jv_InitPrimClass (&_Jv_byteClass,    "byte",    'B', 1);
1289
  _Jv_InitPrimClass (&_Jv_shortClass,   "short",   'S', 2);
1290
  _Jv_InitPrimClass (&_Jv_intClass,     "int",     'I', 4);
1291
  _Jv_InitPrimClass (&_Jv_longClass,    "long",    'J', 8);
1292
  _Jv_InitPrimClass (&_Jv_booleanClass, "boolean", 'Z', 1);
1293
  _Jv_InitPrimClass (&_Jv_charClass,    "char",    'C', 2);
1294
  _Jv_InitPrimClass (&_Jv_floatClass,   "float",   'F', 4);
1295
  _Jv_InitPrimClass (&_Jv_doubleClass,  "double",  'D', 8);
1296
  _Jv_InitPrimClass (&_Jv_voidClass,    "void",    'V', 0);
1297
 
1298
  // Turn stack trace generation off while creating exception objects.
1299
  _Jv_InitClass (&java::lang::VMThrowable::class$);
1300
  java::lang::VMThrowable::trace_enabled = 0;
1301
 
1302
  // We have to initialize this fairly early, to avoid circular class
1303
  // initialization.  In particular we want to start the
1304
  // initialization of ClassLoader before we start the initialization
1305
  // of VMClassLoader.
1306
  _Jv_InitClass (&java::lang::ClassLoader::class$);
1307
 
1308
  // Set up the system class loader and the bootstrap class loader.
1309
  gnu::gcj::runtime::ExtensionClassLoader::initialize();
1310
  java::lang::VMClassLoader::initialize(JvNewStringLatin1(TOOLEXECLIBDIR));
1311
 
1312
  _Jv_RegisterBootstrapPackages();
1313
 
1314
  no_memory = new java::lang::OutOfMemoryError;
1315
 
1316
  java::lang::VMThrowable::trace_enabled = 1;
1317
 
1318
#ifdef USE_LTDL
1319
  LTDL_SET_PRELOADED_SYMBOLS ();
1320
#endif
1321
 
1322
  _Jv_platform_initialize ();
1323
 
1324
  _Jv_JNI_Init ();
1325
 
1326
  _Jv_GCInitializeFinalizers (&::gnu::gcj::runtime::FinalizerThread::finalizerReady);
1327
 
1328
  // Start the GC finalizer thread.  A VirtualMachineError can be
1329
  // thrown by the runtime if, say, threads aren't available.
1330
  try
1331
    {
1332
      using namespace gnu::gcj::runtime;
1333
      FinalizerThread *ft = new FinalizerThread ();
1334
      ft->start ();
1335
    }
1336
  catch (java::lang::VirtualMachineError *ignore)
1337
    {
1338
    }
1339
 
1340
  return 0;
1341
}
1342
 
1343
void
1344
_Jv_RunMain (JvVMInitArgs *vm_args, jclass klass, const char *name, int argc,
1345
             const char **argv, bool is_jar)
1346
{
1347
#ifndef DISABLE_MAIN_ARGS
1348
  _Jv_SetArgs (argc, argv);
1349
#endif
1350
 
1351
  java::lang::Runtime *runtime = NULL;
1352
 
1353
  try
1354
    {
1355
      if (_Jv_CreateJavaVM (vm_args) < 0)
1356
        {
1357
          fprintf (stderr, "libgcj: couldn't create virtual machine\n");
1358
          exit (1);
1359
        }
1360
 
1361
      // Get the Runtime here.  We want to initialize it before searching
1362
      // for `main'; that way it will be set up if `main' is a JNI method.
1363
      runtime = java::lang::Runtime::getRuntime ();
1364
 
1365
#ifdef DISABLE_MAIN_ARGS
1366
      arg_vec = JvConvertArgv (0, 0);
1367
#else      
1368
      arg_vec = JvConvertArgv (argc - 1, argv + 1);
1369
#endif
1370
 
1371
      using namespace gnu::java::lang;
1372
      if (klass)
1373
        main_thread = new MainThread (klass, arg_vec);
1374
      else
1375
        main_thread = new MainThread (JvNewStringLatin1 (name),
1376
                                      arg_vec, is_jar);
1377
    }
1378
  catch (java::lang::Throwable *t)
1379
    {
1380
      java::lang::System::err->println (JvNewStringLatin1
1381
        ("Exception during runtime initialization"));
1382
      t->printStackTrace();
1383
      if (runtime)
1384
        java::lang::Runtime::exitNoChecksAccessor (1);
1385
      // In case the runtime creation failed.
1386
      ::exit (1);
1387
    }
1388
 
1389
  _Jv_AttachCurrentThread (main_thread);
1390
  _Jv_ThreadRun (main_thread);
1391
 
1392
  // If we got here then something went wrong, as MainThread is not
1393
  // supposed to terminate.
1394
  ::exit (1);
1395
}
1396
 
1397
void
1398
_Jv_RunMain (jclass klass, const char *name, int argc, const char **argv,
1399
             bool is_jar)
1400
{
1401
  _Jv_RunMain (NULL, klass, name, argc, argv, is_jar);
1402
}
1403
 
1404
void
1405
JvRunMain (jclass klass, int argc, const char **argv)
1406
{
1407
  _Jv_RunMain (klass, NULL, argc, argv, false);
1408
}
1409
 
1410
 
1411
 
1412
// Parse a string and return a heap size.
1413
static size_t
1414
parse_memory_size (const char *spec)
1415
{
1416
  char *end;
1417
  unsigned long val = strtoul (spec, &end, 10);
1418
  if (*end == 'k' || *end == 'K')
1419
    val *= 1024;
1420
  else if (*end == 'm' || *end == 'M')
1421
    val *= 1048576;
1422
  return (size_t) val;
1423
}
1424
 
1425
// Set the initial heap size.  This might be ignored by the GC layer.
1426
// This must be called before _Jv_RunMain.
1427
void
1428
_Jv_SetInitialHeapSize (const char *arg)
1429
{
1430
  size_t size = parse_memory_size (arg);
1431
  _Jv_GCSetInitialHeapSize (size);
1432
}
1433
 
1434
// Set the maximum heap size.  This might be ignored by the GC layer.
1435
// This must be called before _Jv_RunMain.
1436
void
1437
_Jv_SetMaximumHeapSize (const char *arg)
1438
{
1439
  size_t size = parse_memory_size (arg);
1440
  _Jv_GCSetMaximumHeapSize (size);
1441
}
1442
 
1443
void
1444
_Jv_SetStackSize (const char *arg)
1445
{
1446
  size_t size = parse_memory_size (arg);
1447
  gcj::stack_size = size;
1448
}
1449
 
1450
void *
1451
_Jv_Malloc (jsize size)
1452
{
1453
  if (__builtin_expect (size == 0, false))
1454
    size = 1;
1455
  void *ptr = malloc ((size_t) size);
1456
  if (__builtin_expect (ptr == NULL, false))
1457
    throw no_memory;
1458
  return ptr;
1459
}
1460
 
1461
void *
1462
_Jv_Realloc (void *ptr, jsize size)
1463
{
1464
  if (__builtin_expect (size == 0, false))
1465
    size = 1;
1466
  ptr = realloc (ptr, (size_t) size);
1467
  if (__builtin_expect (ptr == NULL, false))
1468
    throw no_memory;
1469
  return ptr;
1470
}
1471
 
1472
void *
1473
_Jv_MallocUnchecked (jsize size)
1474
{
1475
  if (__builtin_expect (size == 0, false))
1476
    size = 1;
1477
  return malloc ((size_t) size);
1478
}
1479
 
1480
void
1481
_Jv_Free (void* ptr)
1482
{
1483
  return free (ptr);
1484
}
1485
 
1486
 
1487
 
1488
// In theory, these routines can be #ifdef'd away on machines which
1489
// support divide overflow signals.  However, we never know if some
1490
// code might have been compiled with "-fuse-divide-subroutine", so we
1491
// always include them in libgcj.
1492
 
1493
jint
1494
_Jv_divI (jint dividend, jint divisor)
1495
{
1496
  if (__builtin_expect (divisor == 0, false))
1497
    {
1498
      java::lang::ArithmeticException *arithexception
1499
        = new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero"));
1500
      throw arithexception;
1501
    }
1502
 
1503
  if (dividend == (jint) 0x80000000L && divisor == -1)
1504
    return dividend;
1505
 
1506
  return dividend / divisor;
1507
}
1508
 
1509
jint
1510
_Jv_remI (jint dividend, jint divisor)
1511
{
1512
  if (__builtin_expect (divisor == 0, false))
1513
    {
1514
      java::lang::ArithmeticException *arithexception
1515
        = new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero"));
1516
      throw arithexception;
1517
    }
1518
 
1519
  if (dividend == (jint) 0x80000000L && divisor == -1)
1520
    return 0;
1521
 
1522
  return dividend % divisor;
1523
}
1524
 
1525
jlong
1526
_Jv_divJ (jlong dividend, jlong divisor)
1527
{
1528
  if (__builtin_expect (divisor == 0, false))
1529
    {
1530
      java::lang::ArithmeticException *arithexception
1531
        = new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero"));
1532
      throw arithexception;
1533
    }
1534
 
1535
  if (dividend == (jlong) 0x8000000000000000LL && divisor == -1)
1536
    return dividend;
1537
 
1538
  return dividend / divisor;
1539
}
1540
 
1541
jlong
1542
_Jv_remJ (jlong dividend, jlong divisor)
1543
{
1544
  if (__builtin_expect (divisor == 0, false))
1545
    {
1546
      java::lang::ArithmeticException *arithexception
1547
        = new java::lang::ArithmeticException (JvNewStringLatin1 ("/ by zero"));
1548
      throw arithexception;
1549
    }
1550
 
1551
  if (dividend == (jlong) 0x8000000000000000LL && divisor == -1)
1552
    return 0;
1553
 
1554
  return dividend % divisor;
1555
}
1556
 
1557
 
1558
 
1559
// Return true if SELF_KLASS can access a field or method in
1560
// OTHER_KLASS.  The field or method's access flags are specified in
1561
// FLAGS.
1562
jboolean
1563
_Jv_CheckAccess (jclass self_klass, jclass other_klass, jint flags)
1564
{
1565
  using namespace java::lang::reflect;
1566
  return ((self_klass == other_klass)
1567
          || ((flags & Modifier::PUBLIC) != 0)
1568
          || (((flags & Modifier::PROTECTED) != 0)
1569
              && _Jv_IsAssignableFromSlow (self_klass, other_klass))
1570
          || (((flags & Modifier::PRIVATE) == 0)
1571
              && _Jv_ClassNameSamePackage (self_klass->name,
1572
                                           other_klass->name)));
1573
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.