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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [interpret.cc] - Blame information for rev 800

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 753 jeremybenn
// interpret.cc - Code for the interpreter
2
 
3
/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 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
/* Author: Kresten Krab Thorup <krab@gnu.org>  */
12
 
13
#include <config.h>
14
#include <platform.h>
15
 
16
#pragma implementation "java-interp.h"
17
 
18
#include <jvm.h>
19
#include <java-cpool.h>
20
#include <java-interp.h>
21
#include <java/lang/System.h>
22
#include <java/lang/String.h>
23
#include <java/lang/Integer.h>
24
#include <java/lang/Long.h>
25
#include <java/lang/StringBuffer.h>
26
#include <java/lang/Class.h>
27
#include <java/lang/reflect/Modifier.h>
28
#include <java/lang/InternalError.h>
29
#include <java/lang/NullPointerException.h>
30
#include <java/lang/ArithmeticException.h>
31
#include <java/lang/IncompatibleClassChangeError.h>
32
#include <java/lang/InstantiationException.h>
33
#include <java/lang/Thread.h>
34
#include <java-insns.h>
35
#include <java-signal.h>
36
#include <java/lang/ClassFormatError.h>
37
#include <execution.h>
38
#include <java/lang/reflect/Modifier.h>
39
 
40
#include <jvmti.h>
41
#include "jvmti-int.h"
42
 
43
#include <gnu/gcj/jvmti/Breakpoint.h>
44
#include <gnu/gcj/jvmti/BreakpointManager.h>
45
 
46
// Execution engine for interpreted code.
47
_Jv_InterpreterEngine _Jv_soleInterpreterEngine;
48
 
49
#include <stdlib.h>
50
 
51
using namespace gcj;
52
 
53
static void throw_internal_error (const char *msg)
54
  __attribute__ ((__noreturn__));
55
static void throw_incompatible_class_change_error (jstring msg)
56
  __attribute__ ((__noreturn__));
57
static void throw_null_pointer_exception ()
58
  __attribute__ ((__noreturn__));
59
 
60
static void throw_class_format_error (jstring msg)
61
        __attribute__ ((__noreturn__));
62
static void throw_class_format_error (const char *msg)
63
        __attribute__ ((__noreturn__));
64
 
65
static void find_catch_location (jthrowable, jthread, jmethodID *, jlong *);
66
 
67
// A macro to facilitate JVMTI exception reporting
68
#define REPORT_EXCEPTION(Jthrowable)                    \
69
  do {                                                  \
70
    if (JVMTI_REQUESTED_EVENT (Exception))              \
71
      _Jv_ReportJVMTIExceptionThrow (Jthrowable);       \
72
  }                                                     \
73
  while (0)
74
 
75
#ifdef DIRECT_THREADED
76
// Lock to ensure that methods are not compiled concurrently.
77
// We could use a finer-grained lock here, however it is not safe to use
78
// the Class monitor as user code in another thread could hold it.
79
static _Jv_Mutex_t compile_mutex;
80
 
81
// See class ThreadCountAdjuster and REWRITE_INSN for how this is
82
// used.
83
_Jv_Mutex_t _Jv_InterpMethod::rewrite_insn_mutex;
84
 
85
void
86
_Jv_InitInterpreter()
87
{
88
  _Jv_MutexInit (&compile_mutex);
89
  _Jv_MutexInit (&_Jv_InterpMethod::rewrite_insn_mutex);
90
}
91
#else
92
void _Jv_InitInterpreter() {}
93
#endif
94
 
95
// The breakpoint instruction. For the direct threaded case,
96
// _Jv_InterpMethod::compile will initialize breakpoint_insn
97
// the first time it is called.
98
#ifdef DIRECT_THREADED
99
insn_slot _Jv_InterpMethod::bp_insn_slot;
100
pc_t _Jv_InterpMethod::breakpoint_insn = NULL;
101
#else
102
unsigned char _Jv_InterpMethod::bp_insn_opcode
103
  = static_cast<unsigned char> (op_breakpoint);
104
pc_t _Jv_InterpMethod::breakpoint_insn = &_Jv_InterpMethod::bp_insn_opcode;
105
#endif
106
 
107
extern "C" double __ieee754_fmod (double,double);
108
 
109
static inline void dupx (_Jv_word *sp, int n, int x)
110
{
111
  // first "slide" n+x elements n to the right
112
  int top = n-1;
113
  for (int i = 0; i < n+x; i++)
114
    {
115
      sp[(top-i)] = sp[(top-i)-n];
116
    }
117
 
118
  // next, copy the n top elements, n+x down
119
  for (int i = 0; i < n; i++)
120
    {
121
      sp[top-(n+x)-i] = sp[top-i];
122
    }
123
}
124
 
125
// Used to convert from floating types to integral types.
126
template<typename TO, typename FROM>
127
static inline TO
128
convert (FROM val, TO min, TO max)
129
{
130
  TO ret;
131
  if (val >= (FROM) max)
132
    ret = max;
133
  else if (val <= (FROM) min)
134
    ret = min;
135
  else if (val != val)
136
    ret = 0;
137
  else
138
    ret = (TO) val;
139
  return ret;
140
}
141
 
142
#define PUSHA(V)  (sp++)->o = (V)
143
#define PUSHI(V)  (sp++)->i = (V)
144
#define PUSHF(V)  (sp++)->f = (V)
145
#if SIZEOF_VOID_P == 8
146
# define PUSHL(V)   (sp->l = (V), sp += 2)
147
# define PUSHD(V)   (sp->d = (V), sp += 2)
148
#else
149
# define PUSHL(V)  do { _Jv_word2 w2; w2.l=(V); \
150
                        (sp++)->ia[0] = w2.ia[0]; \
151
                        (sp++)->ia[0] = w2.ia[1]; } while (0)
152
# define PUSHD(V)  do { _Jv_word2 w2; w2.d=(V); \
153
                        (sp++)->ia[0] = w2.ia[0]; \
154
                        (sp++)->ia[0] = w2.ia[1]; } while (0)
155
#endif
156
 
157
#define POPA()    ((--sp)->o)
158
#define POPI()    ((jint) (--sp)->i) // cast since it may be promoted
159
#define POPF()    ((jfloat) (--sp)->f)
160
#if SIZEOF_VOID_P == 8
161
# define POPL()   (sp -= 2, (jlong) sp->l)
162
# define POPD()   (sp -= 2, (jdouble) sp->d)
163
#else
164
# define POPL()    ({ _Jv_word2 w2; \
165
                     w2.ia[1] = (--sp)->ia[0]; \
166
                     w2.ia[0] = (--sp)->ia[0]; w2.l; })
167
# define POPD()    ({ _Jv_word2 w2; \
168
                     w2.ia[1] = (--sp)->ia[0]; \
169
                     w2.ia[0] = (--sp)->ia[0]; w2.d; })
170
#endif
171
 
172
#define LOADA(I)  (sp++)->o = locals[I].o
173
#define LOADI(I)  (sp++)->i = locals[I].i
174
#define LOADF(I)  (sp++)->f = locals[I].f
175
#if SIZEOF_VOID_P == 8
176
# define LOADL(I)  (sp->l = locals[I].l, sp += 2)
177
# define LOADD(I)  (sp->d = locals[I].d, sp += 2)
178
#else
179
# define LOADL(I)  do { jint __idx = (I); \
180
                        (sp++)->ia[0] = locals[__idx].ia[0]; \
181
                        (sp++)->ia[0] = locals[__idx+1].ia[0]; \
182
                   } while (0)
183
# define LOADD(I)  LOADL(I)
184
#endif
185
 
186
#define STOREA(I)                       \
187
  do                                    \
188
    {                                   \
189
      jint __idx = (I);                 \
190
      DEBUG_LOCALS_INSN (__idx, 'o');   \
191
      locals[__idx].o = (--sp)->o;      \
192
    }                                   \
193
  while (0)
194
#define STOREI(I)                       \
195
  do                                    \
196
    {                                   \
197
      jint __idx = (I);                 \
198
      DEBUG_LOCALS_INSN (__idx, 'i');   \
199
      locals[__idx].i = (--sp)->i;      \
200
  } while (0)
201
#define STOREF(I)                       \
202
  do                                    \
203
    {                                   \
204
      jint __idx = (I);                 \
205
      DEBUG_LOCALS_INSN (__idx, 'f');   \
206
      locals[__idx].f = (--sp)->f;      \
207
    }                                   \
208
  while (0)
209
#if SIZEOF_VOID_P == 8
210
# define STOREL(I) \
211
  do                                            \
212
    {                                           \
213
      jint __idx = (I);                         \
214
      DEBUG_LOCALS_INSN (__idx, 'l');           \
215
      DEBUG_LOCALS_INSN (__idx + 1, 'x');       \
216
      (sp -= 2, locals[__idx].l = sp->l);       \
217
    }                                           \
218
  while (0)
219
# define STORED(I)                              \
220
  do                                            \
221
    {                                           \
222
      jint __idx = (I);                         \
223
      DEBUG_LOCALS_INSN (__idx, 'd');           \
224
      DEBUG_LOCALS_INSN (__idx + 1, 'x');       \
225
      (sp -= 2, locals[__idx].d = sp->d);       \
226
    }                                           \
227
  while (0)
228
 
229
#else
230
# define STOREL(I)                              \
231
  do                                            \
232
    {                                           \
233
      jint __idx = (I);                         \
234
      DEBUG_LOCALS_INSN (__idx, 'l');           \
235
      DEBUG_LOCALS_INSN (__idx + 1, 'x');       \
236
      locals[__idx + 1].ia[0] = (--sp)->ia[0];    \
237
      locals[__idx].ia[0] = (--sp)->ia[0];        \
238
    }                                           \
239
  while (0)
240
# define STORED(I)                              \
241
  do {                                          \
242
    jint __idx = (I);                           \
243
    DEBUG_LOCALS_INSN (__idx, 'd');             \
244
    DEBUG_LOCALS_INSN (__idx + 1, 'x');         \
245
    locals[__idx + 1].ia[0] = (--sp)->ia[0];      \
246
    locals[__idx].ia[0] = (--sp)->ia[0];  \
247
  } while (0)
248
#endif
249
 
250
#define PEEKI(I)  (locals+(I))->i
251
#define PEEKA(I)  (locals+(I))->o
252
 
253
#define POKEI(I,V)                      \
254
  do                                    \
255
    {                                   \
256
      jint __idx = (I);                 \
257
      DEBUG_LOCALS_INSN (__idx, 'i');   \
258
      ((locals + __idx)->i = (V));      \
259
    }                                   \
260
  while (0)
261
 
262
 
263
#define BINOPI(OP) { \
264
   jint value2 = POPI(); \
265
   jint value1 = POPI(); \
266
   PUSHI(value1 OP value2); \
267
}
268
 
269
#define BINOPF(OP) { \
270
   jfloat value2 = POPF(); \
271
   jfloat value1 = POPF(); \
272
   PUSHF(value1 OP value2); \
273
}
274
 
275
#define BINOPL(OP) { \
276
   jlong value2 = POPL(); \
277
   jlong value1 = POPL(); \
278
   PUSHL(value1 OP value2); \
279
}
280
 
281
#define BINOPD(OP) { \
282
   jdouble value2 = POPD(); \
283
   jdouble value1 = POPD(); \
284
   PUSHD(value1 OP value2); \
285
}
286
 
287
static inline jint
288
get1s (unsigned char* loc)
289
{
290
  return *(signed char*)loc;
291
}
292
 
293
static inline jint
294
get1u (unsigned char* loc)
295
{
296
  return *loc;
297
}
298
 
299
static inline jint
300
get2s(unsigned char* loc)
301
{
302
  return (((jint)*(signed char*)loc) << 8) | ((jint)*(loc+1));
303
}
304
 
305
static inline jint
306
get2u (unsigned char* loc)
307
{
308
  return (((jint)(*loc)) << 8) | ((jint)*(loc+1));
309
}
310
 
311
static jint
312
get4 (unsigned char* loc)
313
{
314
  return (((jint)(loc[0])) << 24)
315
       | (((jint)(loc[1])) << 16)
316
       | (((jint)(loc[2])) << 8)
317
       | (((jint)(loc[3])) << 0);
318
}
319
 
320
#define SAVE_PC() frame_desc.pc = pc
321
 
322
// We used to define this conditionally, depending on HANDLE_SEGV.
323
// However, that runs into a problem if a chunk in low memory is
324
// mapped and we try to look at a field near the end of a large
325
// object.  See PR 26858 for details.  It is, most likely, relatively
326
// inexpensive to simply do this check always.
327
#define NULLCHECK(X) \
328
  do { SAVE_PC(); if ((X)==NULL) throw_null_pointer_exception (); } while (0)
329
 
330
// Note that we can still conditionally define NULLARRAYCHECK, since
331
// we know that all uses of an array will first reference the length
332
// field, which is first -- and thus will trigger a SEGV.
333
#ifdef HANDLE_SEGV
334
#define NULLARRAYCHECK(X) SAVE_PC()
335
#else
336
#define NULLARRAYCHECK(X)                                       \
337
  do                                                            \
338
    {                                                           \
339
      SAVE_PC();                                                \
340
      if ((X) == NULL) { throw_null_pointer_exception (); }     \
341
    } while (0)
342
#endif
343
 
344
#define ARRAYBOUNDSCHECK(array, index)                          \
345
  do                                                            \
346
    {                                                           \
347
      if (((unsigned) index) >= (unsigned) (array->length))     \
348
        _Jv_ThrowBadArrayIndex (index);                         \
349
    } while (0)
350
 
351
void
352
_Jv_InterpMethod::run_normal (ffi_cif *,
353
                              void *ret,
354
                              INTERP_FFI_RAW_TYPE *args,
355
                              void *__this)
356
{
357
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
358
  run (ret, args, _this);
359
}
360
 
361
void
362
_Jv_InterpMethod::run_normal_debug (ffi_cif *,
363
                                    void *ret,
364
                                    INTERP_FFI_RAW_TYPE *args,
365
                                    void *__this)
366
{
367
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
368
  run_debug (ret, args, _this);
369
}
370
 
371
void
372
_Jv_InterpMethod::run_synch_object (ffi_cif *,
373
                                    void *ret,
374
                                    INTERP_FFI_RAW_TYPE *args,
375
                                    void *__this)
376
{
377
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
378
 
379
  jobject rcv = (jobject) args[0].ptr;
380
  JvSynchronize mutex (rcv);
381
 
382
  run (ret, args, _this);
383
}
384
 
385
void
386
_Jv_InterpMethod::run_synch_object_debug (ffi_cif *,
387
                                          void *ret,
388
                                          INTERP_FFI_RAW_TYPE *args,
389
                                          void *__this)
390
{
391
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
392
 
393
  jobject rcv = (jobject) args[0].ptr;
394
  JvSynchronize mutex (rcv);
395
 
396
  run_debug (ret, args, _this);
397
}
398
 
399
void
400
_Jv_InterpMethod::run_class (ffi_cif *,
401
                             void *ret,
402
                             INTERP_FFI_RAW_TYPE *args,
403
                             void *__this)
404
{
405
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
406
  _Jv_InitClass (_this->defining_class);
407
  run (ret, args, _this);
408
}
409
 
410
void
411
_Jv_InterpMethod::run_class_debug (ffi_cif *,
412
                                   void *ret,
413
                                   INTERP_FFI_RAW_TYPE *args,
414
                                   void *__this)
415
{
416
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
417
  _Jv_InitClass (_this->defining_class);
418
  run_debug (ret, args, _this);
419
}
420
 
421
void
422
_Jv_InterpMethod::run_synch_class (ffi_cif *,
423
                                   void *ret,
424
                                   INTERP_FFI_RAW_TYPE *args,
425
                                   void *__this)
426
{
427
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
428
 
429
  jclass sync = _this->defining_class;
430
  _Jv_InitClass (sync);
431
  JvSynchronize mutex (sync);
432
 
433
  run (ret, args, _this);
434
}
435
 
436
void
437
_Jv_InterpMethod::run_synch_class_debug (ffi_cif *,
438
                                         void *ret,
439
                                         INTERP_FFI_RAW_TYPE *args,
440
                                         void *__this)
441
{
442
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
443
 
444
  jclass sync = _this->defining_class;
445
  _Jv_InitClass (sync);
446
  JvSynchronize mutex (sync);
447
 
448
  run_debug (ret, args, _this);
449
}
450
 
451
#ifdef DIRECT_THREADED
452
// "Compile" a method by turning it from bytecode to direct-threaded
453
// code.
454
void
455
_Jv_InterpMethod::compile (const void * const *insn_targets)
456
{
457
  insn_slot *insns = NULL;
458
  int next = 0;
459
  unsigned char *codestart = bytecode ();
460
  unsigned char *end = codestart + code_length;
461
  _Jv_word *pool_data = defining_class->constants.data;
462
 
463
#define SET_ONE(Field, Value)                                                 \
464
  do                                                                          \
465
    {                                                                         \
466
      if (first_pass)                                                         \
467
        ++next;                                                               \
468
      else                                                                    \
469
        insns[next++].Field = Value;                                          \
470
    }                                                                         \
471
  while (0)
472
 
473
#define SET_INSN(Value) SET_ONE (insn, (void *) Value)
474
#define SET_INT(Value) SET_ONE (int_val, Value)
475
#define SET_DATUM(Value) SET_ONE (datum, Value)
476
 
477
  // Map from bytecode PC to slot in INSNS.
478
  int *pc_mapping = (int *) __builtin_alloca (sizeof (int) * code_length);
479
  for (int i = 0; i < code_length; ++i)
480
    pc_mapping[i] = -1;
481
 
482
  for (int i = 0; i < 2; ++i)
483
    {
484
      jboolean first_pass = i == 0;
485
 
486
      if (! first_pass)
487
        {
488
          insns = (insn_slot *) _Jv_AllocBytes (sizeof (insn_slot) * next);
489
          number_insn_slots = next;
490
          next = 0;
491
        }
492
 
493
      unsigned char *pc = codestart;
494
      while (pc < end)
495
        {
496
          int base_pc_val = pc - codestart;
497
          if (first_pass)
498
            pc_mapping[base_pc_val] = next;
499
 
500
          java_opcode opcode = (java_opcode) *pc++;
501
          // Just elide NOPs.
502
          if (opcode == op_nop)
503
            continue;
504
          SET_INSN (insn_targets[opcode]);
505
 
506
          switch (opcode)
507
            {
508
            case op_nop:
509
            case op_aconst_null:
510
            case op_iconst_m1:
511
            case op_iconst_0:
512
            case op_iconst_1:
513
            case op_iconst_2:
514
            case op_iconst_3:
515
            case op_iconst_4:
516
            case op_iconst_5:
517
            case op_lconst_0:
518
            case op_lconst_1:
519
            case op_fconst_0:
520
            case op_fconst_1:
521
            case op_fconst_2:
522
            case op_dconst_0:
523
            case op_dconst_1:
524
            case op_iload_0:
525
            case op_iload_1:
526
            case op_iload_2:
527
            case op_iload_3:
528
            case op_lload_0:
529
            case op_lload_1:
530
            case op_lload_2:
531
            case op_lload_3:
532
            case op_fload_0:
533
            case op_fload_1:
534
            case op_fload_2:
535
            case op_fload_3:
536
            case op_dload_0:
537
            case op_dload_1:
538
            case op_dload_2:
539
            case op_dload_3:
540
            case op_aload_0:
541
            case op_aload_1:
542
            case op_aload_2:
543
            case op_aload_3:
544
            case op_iaload:
545
            case op_laload:
546
            case op_faload:
547
            case op_daload:
548
            case op_aaload:
549
            case op_baload:
550
            case op_caload:
551
            case op_saload:
552
            case op_istore_0:
553
            case op_istore_1:
554
            case op_istore_2:
555
            case op_istore_3:
556
            case op_lstore_0:
557
            case op_lstore_1:
558
            case op_lstore_2:
559
            case op_lstore_3:
560
            case op_fstore_0:
561
            case op_fstore_1:
562
            case op_fstore_2:
563
            case op_fstore_3:
564
            case op_dstore_0:
565
            case op_dstore_1:
566
            case op_dstore_2:
567
            case op_dstore_3:
568
            case op_astore_0:
569
            case op_astore_1:
570
            case op_astore_2:
571
            case op_astore_3:
572
            case op_iastore:
573
            case op_lastore:
574
            case op_fastore:
575
            case op_dastore:
576
            case op_aastore:
577
            case op_bastore:
578
            case op_castore:
579
            case op_sastore:
580
            case op_pop:
581
            case op_pop2:
582
            case op_dup:
583
            case op_dup_x1:
584
            case op_dup_x2:
585
            case op_dup2:
586
            case op_dup2_x1:
587
            case op_dup2_x2:
588
            case op_swap:
589
            case op_iadd:
590
            case op_isub:
591
            case op_imul:
592
            case op_idiv:
593
            case op_irem:
594
            case op_ishl:
595
            case op_ishr:
596
            case op_iushr:
597
            case op_iand:
598
            case op_ior:
599
            case op_ixor:
600
            case op_ladd:
601
            case op_lsub:
602
            case op_lmul:
603
            case op_ldiv:
604
            case op_lrem:
605
            case op_lshl:
606
            case op_lshr:
607
            case op_lushr:
608
            case op_land:
609
            case op_lor:
610
            case op_lxor:
611
            case op_fadd:
612
            case op_fsub:
613
            case op_fmul:
614
            case op_fdiv:
615
            case op_frem:
616
            case op_dadd:
617
            case op_dsub:
618
            case op_dmul:
619
            case op_ddiv:
620
            case op_drem:
621
            case op_ineg:
622
            case op_i2b:
623
            case op_i2c:
624
            case op_i2s:
625
            case op_lneg:
626
            case op_fneg:
627
            case op_dneg:
628
            case op_i2l:
629
            case op_i2f:
630
            case op_i2d:
631
            case op_l2i:
632
            case op_l2f:
633
            case op_l2d:
634
            case op_f2i:
635
            case op_f2l:
636
            case op_f2d:
637
            case op_d2i:
638
            case op_d2l:
639
            case op_d2f:
640
            case op_lcmp:
641
            case op_fcmpl:
642
            case op_fcmpg:
643
            case op_dcmpl:
644
            case op_dcmpg:
645
            case op_monitorenter:
646
            case op_monitorexit:
647
            case op_ireturn:
648
            case op_lreturn:
649
            case op_freturn:
650
            case op_dreturn:
651
            case op_areturn:
652
            case op_return:
653
            case op_athrow:
654
            case op_arraylength:
655
              // No argument, nothing else to do.
656
              break;
657
 
658
            case op_bipush:
659
              SET_INT (get1s (pc));
660
              ++pc;
661
              break;
662
 
663
            case op_ldc:
664
              {
665
                int index = get1u (pc);
666
                ++pc;
667
                // For an unresolved class we want to delay resolution
668
                // until execution.
669
                if (defining_class->constants.tags[index] == JV_CONSTANT_Class)
670
                  {
671
                    --next;
672
                    SET_INSN (insn_targets[int (op_jsr_w) + 1]);
673
                    SET_INT (index);
674
                  }
675
                else
676
                  SET_DATUM (pool_data[index].o);
677
              }
678
              break;
679
 
680
            case op_ret:
681
            case op_iload:
682
            case op_lload:
683
            case op_fload:
684
            case op_dload:
685
            case op_aload:
686
            case op_istore:
687
            case op_lstore:
688
            case op_fstore:
689
            case op_dstore:
690
            case op_astore:
691
            case op_newarray:
692
              SET_INT (get1u (pc));
693
              ++pc;
694
              break;
695
 
696
            case op_iinc:
697
              SET_INT (get1u (pc));
698
              SET_INT (get1s (pc + 1));
699
              pc += 2;
700
              break;
701
 
702
            case op_ldc_w:
703
              {
704
                int index = get2u (pc);
705
                pc += 2;
706
                // For an unresolved class we want to delay resolution
707
                // until execution.
708
                if (defining_class->constants.tags[index] == JV_CONSTANT_Class)
709
                  {
710
                    --next;
711
                    SET_INSN (insn_targets[int (op_jsr_w) + 1]);
712
                    SET_INT (index);
713
                  }
714
                else
715
                  SET_DATUM (pool_data[index].o);
716
              }
717
              break;
718
 
719
            case op_ldc2_w:
720
              {
721
                int index = get2u (pc);
722
                pc += 2;
723
                SET_DATUM (&pool_data[index]);
724
              }
725
              break;
726
 
727
            case op_sipush:
728
              SET_INT (get2s (pc));
729
              pc += 2;
730
              break;
731
 
732
            case op_new:
733
            case op_getstatic:
734
            case op_getfield:
735
            case op_putfield:
736
            case op_putstatic:
737
            case op_anewarray:
738
            case op_instanceof:
739
            case op_checkcast:
740
            case op_invokespecial:
741
            case op_invokestatic:
742
            case op_invokevirtual:
743
              SET_INT (get2u (pc));
744
              pc += 2;
745
              break;
746
 
747
            case op_multianewarray:
748
              SET_INT (get2u (pc));
749
              SET_INT (get1u (pc + 2));
750
              pc += 3;
751
              break;
752
 
753
            case op_jsr:
754
            case op_ifeq:
755
            case op_ifne:
756
            case op_iflt:
757
            case op_ifge:
758
            case op_ifgt:
759
            case op_ifle:
760
            case op_if_icmpeq:
761
            case op_if_icmpne:
762
            case op_if_icmplt:
763
            case op_if_icmpge:
764
            case op_if_icmpgt:
765
            case op_if_icmple:
766
            case op_if_acmpeq:
767
            case op_if_acmpne:
768
            case op_ifnull:
769
            case op_ifnonnull:
770
            case op_goto:
771
              {
772
                int offset = get2s (pc);
773
                pc += 2;
774
 
775
                int new_pc = base_pc_val + offset;
776
 
777
                bool orig_was_goto = opcode == op_goto;
778
 
779
                // Thread jumps.  We limit the loop count; this lets
780
                // us avoid infinite loops if the bytecode contains
781
                // such.  `10' is arbitrary.
782
                int count = 10;
783
                while (codestart[new_pc] == op_goto && count-- > 0)
784
                  new_pc += get2s (&codestart[new_pc + 1]);
785
 
786
                // If the jump takes us to a `return' instruction and
787
                // the original branch was an unconditional goto, then
788
                // we hoist the return.
789
                opcode = (java_opcode) codestart[new_pc];
790
                if (orig_was_goto
791
                    && (opcode == op_ireturn || opcode == op_lreturn
792
                        || opcode == op_freturn || opcode == op_dreturn
793
                        || opcode == op_areturn || opcode == op_return))
794
                  {
795
                    --next;
796
                    SET_INSN (insn_targets[opcode]);
797
                  }
798
                else
799
                  SET_DATUM (&insns[pc_mapping[new_pc]]);
800
              }
801
              break;
802
 
803
            case op_tableswitch:
804
              {
805
                while ((pc - codestart) % 4 != 0)
806
                  ++pc;
807
 
808
                jint def = get4 (pc);
809
                SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
810
                pc += 4;
811
 
812
                int low = get4 (pc);
813
                SET_INT (low);
814
                pc += 4;
815
                int high = get4 (pc);
816
                SET_INT (high);
817
                pc += 4;
818
 
819
                for (int i = low; i <= high; ++i)
820
                  {
821
                    SET_DATUM (&insns[pc_mapping[base_pc_val + get4 (pc)]]);
822
                    pc += 4;
823
                  }
824
              }
825
              break;
826
 
827
            case op_lookupswitch:
828
              {
829
                while ((pc - codestart) % 4 != 0)
830
                  ++pc;
831
 
832
                jint def = get4 (pc);
833
                SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
834
                pc += 4;
835
 
836
                jint npairs = get4 (pc);
837
                pc += 4;
838
                SET_INT (npairs);
839
 
840
                while (npairs-- > 0)
841
                  {
842
                    jint match = get4 (pc);
843
                    jint offset = get4 (pc + 4);
844
                    SET_INT (match);
845
                    SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
846
                    pc += 8;
847
                  }
848
              }
849
              break;
850
 
851
            case op_invokeinterface:
852
              {
853
                jint index = get2u (pc);
854
                pc += 2;
855
                // We ignore the next two bytes.
856
                pc += 2;
857
                SET_INT (index);
858
              }
859
              break;
860
 
861
            case op_wide:
862
              {
863
                opcode = (java_opcode) get1u (pc);
864
                pc += 1;
865
                jint val = get2u (pc);
866
                pc += 2;
867
 
868
                // We implement narrow and wide instructions using the
869
                // same code in the interpreter.  So we rewrite the
870
                // instruction slot here.
871
                if (! first_pass)
872
                  insns[next - 1].insn = (void *) insn_targets[opcode];
873
                SET_INT (val);
874
 
875
                if (opcode == op_iinc)
876
                  {
877
                    SET_INT (get2s (pc));
878
                    pc += 2;
879
                  }
880
              }
881
              break;
882
 
883
            case op_jsr_w:
884
            case op_goto_w:
885
              {
886
                jint offset = get4 (pc);
887
                pc += 4;
888
                SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
889
              }
890
              break;
891
 
892
            // Some "can't happen" cases that we include for
893
            // error-checking purposes.
894
            case op_putfield_1:
895
            case op_putfield_2:
896
            case op_putfield_4:
897
            case op_putfield_8:
898
            case op_putfield_a:
899
            case op_putstatic_1:
900
            case op_putstatic_2:
901
            case op_putstatic_4:
902
            case op_putstatic_8:
903
            case op_putstatic_a:
904
            case op_getfield_1:
905
            case op_getfield_2s:
906
            case op_getfield_2u:
907
            case op_getfield_4:
908
            case op_getfield_8:
909
            case op_getfield_a:
910
            case op_getstatic_1:
911
            case op_getstatic_2s:
912
            case op_getstatic_2u:
913
            case op_getstatic_4:
914
            case op_getstatic_8:
915
            case op_getstatic_a:
916
            case op_breakpoint:
917
            default:
918
              // Fail somehow.
919
              break;
920
            }
921
        }
922
    }
923
 
924
  // Now update exceptions.
925
  _Jv_InterpException *exc = exceptions ();
926
  for (int i = 0; i < exc_count; ++i)
927
    {
928
      exc[i].start_pc.p = &insns[pc_mapping[exc[i].start_pc.i]];
929
      exc[i].end_pc.p = &insns[pc_mapping[exc[i].end_pc.i]];
930
      exc[i].handler_pc.p = &insns[pc_mapping[exc[i].handler_pc.i]];
931
      // FIXME: resolve_pool_entry can throw - we shouldn't be doing this
932
      // during compilation.
933
      jclass handler
934
        = (_Jv_Linker::resolve_pool_entry (defining_class,
935
                                             exc[i].handler_type.i)).clazz;
936
      exc[i].handler_type.p = handler;
937
    }
938
 
939
  // Translate entries in the LineNumberTable from bytecode PC's to direct
940
  // threaded interpreter instruction values.
941
  for (int i = 0; i < line_table_len; i++)
942
    {
943
      int byte_pc = line_table[i].bytecode_pc;
944
      // It isn't worth throwing an exception if this table is
945
      // corrupted, but at the same time we don't want a crash.
946
      if (byte_pc < 0 || byte_pc >= code_length)
947
        byte_pc = 0;
948
      line_table[i].pc = &insns[pc_mapping[byte_pc]];
949
    }
950
 
951
  prepared = insns;
952
 
953
  // Now remap the variable table for this method.
954
  for (int i = 0; i < local_var_table_len; ++i)
955
    {
956
      int start_byte = local_var_table[i].bytecode_pc;
957
      if (start_byte < 0 || start_byte >= code_length)
958
        start_byte = 0;
959
      jlocation start =  pc_mapping[start_byte];
960
 
961
      int end_byte = start_byte + local_var_table[i].length;
962
      if (end_byte < 0)
963
        end_byte = 0;
964
      jlocation end = ((end_byte >= code_length)
965
                       ? number_insn_slots
966
                       : pc_mapping[end_byte]);
967
 
968
      local_var_table[i].pc = &insns[start];
969
      local_var_table[i].length = end - start + 1;
970
    }
971
 
972
  if (breakpoint_insn == NULL)
973
    {
974
      bp_insn_slot.insn = const_cast<void *> (insn_targets[op_breakpoint]);
975
      breakpoint_insn = &bp_insn_slot;
976
    }
977
}
978
#endif /* DIRECT_THREADED */
979
 
980
/* Run the given method.
981
   When args is NULL, don't run anything -- just compile it. */
982
void
983
_Jv_InterpMethod::run (void *retp, INTERP_FFI_RAW_TYPE *args,
984
                       _Jv_InterpMethod *meth)
985
{
986
#undef __GCJ_DEBUG
987
#undef DEBUG_LOCALS_INSN
988
#define DEBUG_LOCALS_INSN(s, t) do {} while (0)
989
 
990
#include "interpret-run.cc"
991
}
992
 
993
void
994
_Jv_InterpMethod::run_debug (void *retp, INTERP_FFI_RAW_TYPE *args,
995
                             _Jv_InterpMethod *meth)
996
{
997
#define __GCJ_DEBUG
998
#undef DEBUG_LOCALS_INSN
999
#define DEBUG_LOCALS_INSN(s, t)  \
1000
  do    \
1001
    {   \
1002
      frame_desc.locals_type[s] = t;  \
1003
    }   \
1004
  while (0)
1005
 
1006
#include "interpret-run.cc"
1007
}
1008
 
1009
static void
1010
throw_internal_error (const char *msg)
1011
{
1012
  jthrowable t = new java::lang::InternalError (JvNewStringLatin1 (msg));
1013
  REPORT_EXCEPTION (t);
1014
  throw t;
1015
}
1016
 
1017
static void
1018
throw_incompatible_class_change_error (jstring msg)
1019
{
1020
  jthrowable t = new java::lang::IncompatibleClassChangeError (msg);
1021
  REPORT_EXCEPTION (t);
1022
  throw t;
1023
}
1024
 
1025
static void
1026
throw_null_pointer_exception ()
1027
{
1028
  jthrowable t = new java::lang::NullPointerException;
1029
  REPORT_EXCEPTION (t);
1030
  throw t;
1031
}
1032
 
1033
/* Look up source code line number for given bytecode (or direct threaded
1034
   interpreter) PC. */
1035
int
1036
_Jv_InterpMethod::get_source_line(pc_t mpc)
1037
{
1038
  int line = line_table_len > 0 ? line_table[0].line : -1;
1039
  for (int i = 1; i < line_table_len; i++)
1040
    if (line_table[i].pc > mpc)
1041
      break;
1042
    else
1043
      line = line_table[i].line;
1044
 
1045
  return line;
1046
}
1047
 
1048
/** Do static initialization for fields with a constant initializer */
1049
void
1050
_Jv_InitField (jobject obj, jclass klass, int index)
1051
{
1052
  using namespace java::lang::reflect;
1053
 
1054
  if (obj != 0 && klass == 0)
1055
    klass = obj->getClass ();
1056
 
1057
  if (!_Jv_IsInterpretedClass (klass))
1058
    return;
1059
 
1060
  _Jv_InterpClass *iclass = (_Jv_InterpClass*)klass->aux_info;
1061
 
1062
  _Jv_Field * field = (&klass->fields[0]) + index;
1063
 
1064
  if (index > klass->field_count)
1065
    throw_internal_error ("field out of range");
1066
 
1067
  int init = iclass->field_initializers[index];
1068
  if (init == 0)
1069
    return;
1070
 
1071
  _Jv_Constants *pool = &klass->constants;
1072
  int tag = pool->tags[init];
1073
 
1074
  if (! field->isResolved ())
1075
    throw_internal_error ("initializing unresolved field");
1076
 
1077
  if (obj==0 && ((field->flags & Modifier::STATIC) == 0))
1078
    throw_internal_error ("initializing non-static field with no object");
1079
 
1080
  void *addr = 0;
1081
 
1082
  if ((field->flags & Modifier::STATIC) != 0)
1083
    addr = (void*) field->u.addr;
1084
  else
1085
    addr = (void*) (((char*)obj) + field->u.boffset);
1086
 
1087
  switch (tag)
1088
    {
1089
    case JV_CONSTANT_String:
1090
      {
1091
        jstring str;
1092
        str = _Jv_NewStringUtf8Const (pool->data[init].utf8);
1093
        pool->data[init].string = str;
1094
        pool->tags[init] = JV_CONSTANT_ResolvedString;
1095
      }
1096
      /* fall through */
1097
 
1098
    case JV_CONSTANT_ResolvedString:
1099
      if (! (field->type == &java::lang::String::class$
1100
             || field->type == &java::lang::Class::class$))
1101
        throw_class_format_error ("string initialiser to non-string field");
1102
 
1103
      *(jstring*)addr = pool->data[init].string;
1104
      break;
1105
 
1106
    case JV_CONSTANT_Integer:
1107
      {
1108
        int value = pool->data[init].i;
1109
 
1110
        if (field->type == JvPrimClass (boolean))
1111
          *(jboolean*)addr = (jboolean)value;
1112
 
1113
        else if (field->type == JvPrimClass (byte))
1114
          *(jbyte*)addr = (jbyte)value;
1115
 
1116
        else if (field->type == JvPrimClass (char))
1117
          *(jchar*)addr = (jchar)value;
1118
 
1119
        else if (field->type == JvPrimClass (short))
1120
          *(jshort*)addr = (jshort)value;
1121
 
1122
        else if (field->type == JvPrimClass (int))
1123
          *(jint*)addr = (jint)value;
1124
 
1125
        else
1126
          throw_class_format_error ("erroneous field initializer");
1127
      }
1128
      break;
1129
 
1130
    case JV_CONSTANT_Long:
1131
      if (field->type != JvPrimClass (long))
1132
        throw_class_format_error ("erroneous field initializer");
1133
 
1134
      *(jlong*)addr = _Jv_loadLong (&pool->data[init]);
1135
      break;
1136
 
1137
    case JV_CONSTANT_Float:
1138
      if (field->type != JvPrimClass (float))
1139
        throw_class_format_error ("erroneous field initializer");
1140
 
1141
      *(jfloat*)addr = pool->data[init].f;
1142
      break;
1143
 
1144
    case JV_CONSTANT_Double:
1145
      if (field->type != JvPrimClass (double))
1146
        throw_class_format_error ("erroneous field initializer");
1147
 
1148
      *(jdouble*)addr = _Jv_loadDouble (&pool->data[init]);
1149
      break;
1150
 
1151
    default:
1152
      throw_class_format_error ("erroneous field initializer");
1153
    }
1154
}
1155
 
1156
inline static unsigned char*
1157
skip_one_type (unsigned char* ptr)
1158
{
1159
  int ch = *ptr++;
1160
 
1161
  while (ch == '[')
1162
    {
1163
      ch = *ptr++;
1164
    }
1165
 
1166
  if (ch == 'L')
1167
    {
1168
      do { ch = *ptr++; } while (ch != ';');
1169
    }
1170
 
1171
  return ptr;
1172
}
1173
 
1174
static ffi_type*
1175
get_ffi_type_from_signature (unsigned char* ptr)
1176
{
1177
  switch (*ptr)
1178
    {
1179
    case 'L':
1180
    case '[':
1181
      return &ffi_type_pointer;
1182
      break;
1183
 
1184
    case 'Z':
1185
      // On some platforms a bool is a byte, on others an int.
1186
      if (sizeof (jboolean) == sizeof (jbyte))
1187
        return &ffi_type_sint8;
1188
      else
1189
        {
1190
          JvAssert (sizeof (jbyte) == sizeof (jint));
1191
          return &ffi_type_sint32;
1192
        }
1193
      break;
1194
 
1195
    case 'B':
1196
      return &ffi_type_sint8;
1197
      break;
1198
 
1199
    case 'C':
1200
      return &ffi_type_uint16;
1201
      break;
1202
 
1203
    case 'S':
1204
      return &ffi_type_sint16;
1205
      break;
1206
 
1207
    case 'I':
1208
      return &ffi_type_sint32;
1209
      break;
1210
 
1211
    case 'J':
1212
      return &ffi_type_sint64;
1213
      break;
1214
 
1215
    case 'F':
1216
      return &ffi_type_float;
1217
      break;
1218
 
1219
    case 'D':
1220
      return &ffi_type_double;
1221
      break;
1222
 
1223
    case 'V':
1224
      return &ffi_type_void;
1225
      break;
1226
    }
1227
 
1228
  throw_internal_error ("unknown type in signature");
1229
}
1230
 
1231
/* this function yields the number of actual arguments, that is, if the
1232
 * function is non-static, then one is added to the number of elements
1233
 * found in the signature */
1234
 
1235
int
1236
_Jv_count_arguments (_Jv_Utf8Const *signature,
1237
                     jboolean staticp)
1238
{
1239
  unsigned char *ptr = (unsigned char*) signature->chars();
1240
  int arg_count = staticp ? 0 : 1;
1241
 
1242
  /* first, count number of arguments */
1243
 
1244
  // skip '('
1245
  ptr++;
1246
 
1247
  // count args
1248
  while (*ptr != ')')
1249
    {
1250
      ptr = skip_one_type (ptr);
1251
      arg_count += 1;
1252
    }
1253
 
1254
  return arg_count;
1255
}
1256
 
1257
/* This beast will build a cif, given the signature.  Memory for
1258
 * the cif itself and for the argument types must be allocated by the
1259
 * caller.
1260
 */
1261
 
1262
int
1263
_Jv_init_cif (_Jv_Utf8Const* signature,
1264
              int arg_count,
1265
              jboolean staticp,
1266
              ffi_cif *cif,
1267
              ffi_type **arg_types,
1268
              ffi_type **rtype_p)
1269
{
1270
  unsigned char *ptr = (unsigned char*) signature->chars();
1271
 
1272
  int arg_index = 0;             // arg number
1273
  int item_count = 0;            // stack-item count
1274
 
1275
  // setup receiver
1276
  if (!staticp)
1277
    {
1278
      arg_types[arg_index++] = &ffi_type_pointer;
1279
      item_count += 1;
1280
    }
1281
 
1282
  // skip '('
1283
  ptr++;
1284
 
1285
  // assign arg types
1286
  while (*ptr != ')')
1287
    {
1288
      arg_types[arg_index++] = get_ffi_type_from_signature (ptr);
1289
 
1290
      if (*ptr == 'J' || *ptr == 'D')
1291
        item_count += 2;
1292
      else
1293
        item_count += 1;
1294
 
1295
      ptr = skip_one_type (ptr);
1296
    }
1297
 
1298
  // skip ')'
1299
  ptr++;
1300
  ffi_type *rtype = get_ffi_type_from_signature (ptr);
1301
 
1302
  ptr = skip_one_type (ptr);
1303
  if (ptr != (unsigned char*)signature->chars() + signature->len())
1304
    throw_internal_error ("did not find end of signature");
1305
 
1306
  ffi_abi cabi = FFI_DEFAULT_ABI;
1307
#if defined (X86_WIN32) && !defined (__CYGWIN__)
1308
  if (!staticp)
1309
    cabi = FFI_THISCALL;
1310
#endif
1311
  if (ffi_prep_cif (cif, cabi,
1312
                    arg_count, rtype, arg_types) != FFI_OK)
1313
    throw_internal_error ("ffi_prep_cif failed");
1314
 
1315
  if (rtype_p != NULL)
1316
    *rtype_p = rtype;
1317
 
1318
  return item_count;
1319
}
1320
 
1321
/* we put this one here, and not in interpret.cc because it
1322
 * calls the utility routines _Jv_count_arguments
1323
 * which are static to this module.  The following struct defines the
1324
 * layout we use for the stubs, it's only used in the ncode method. */
1325
 
1326
#if FFI_NATIVE_RAW_API
1327
#   define FFI_PREP_RAW_CLOSURE ffi_prep_raw_closure_loc
1328
#   define FFI_RAW_SIZE ffi_raw_size
1329
typedef struct {
1330
  ffi_raw_closure  closure;
1331
  _Jv_ClosureList list;
1332
  ffi_cif   cif;
1333
  ffi_type *arg_types[0];
1334
} ncode_closure;
1335
typedef void (*ffi_closure_fun) (ffi_cif*,void*,INTERP_FFI_RAW_TYPE*,void*);
1336
#else
1337
#   define FFI_PREP_RAW_CLOSURE ffi_prep_java_raw_closure_loc
1338
#   define FFI_RAW_SIZE ffi_java_raw_size
1339
typedef struct {
1340
  ffi_java_raw_closure  closure;
1341
  _Jv_ClosureList list;
1342
  ffi_cif   cif;
1343
  ffi_type *arg_types[0];
1344
} ncode_closure;
1345
typedef void (*ffi_closure_fun) (ffi_cif*,void*,ffi_java_raw*,void*);
1346
#endif
1347
 
1348
void *
1349
_Jv_InterpMethod::ncode (jclass klass)
1350
{
1351
  using namespace java::lang::reflect;
1352
 
1353
  if (self->ncode != 0)
1354
    return self->ncode;
1355
 
1356
  jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
1357
  int arg_count = _Jv_count_arguments (self->signature, staticp);
1358
 
1359
  void *code;
1360
  ncode_closure *closure =
1361
    (ncode_closure*)ffi_closure_alloc (sizeof (ncode_closure)
1362
                                       + arg_count * sizeof (ffi_type*),
1363
                                       &code);
1364
  closure->list.registerClosure (klass, closure);
1365
 
1366
  _Jv_init_cif (self->signature,
1367
                arg_count,
1368
                staticp,
1369
                &closure->cif,
1370
                &closure->arg_types[0],
1371
                NULL);
1372
 
1373
  ffi_closure_fun fun;
1374
 
1375
  args_raw_size = FFI_RAW_SIZE (&closure->cif);
1376
 
1377
  JvAssert ((self->accflags & Modifier::NATIVE) == 0);
1378
 
1379
  if ((self->accflags & Modifier::SYNCHRONIZED) != 0)
1380
    {
1381
      if (staticp)
1382
        {
1383
          if (JVMTI::enabled)
1384
            fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_class_debug;
1385
          else
1386
            fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_class;
1387
        }
1388
      else
1389
        {
1390
          if (JVMTI::enabled)
1391
            fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_object_debug;
1392
          else
1393
            fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_object;
1394
        }
1395
    }
1396
  else
1397
    {
1398
      if (staticp)
1399
        {
1400
          if (JVMTI::enabled)
1401
            fun = (ffi_closure_fun)&_Jv_InterpMethod::run_class_debug;
1402
          else
1403
            fun = (ffi_closure_fun)&_Jv_InterpMethod::run_class;
1404
        }
1405
      else
1406
        {
1407
          if (JVMTI::enabled)
1408
            fun = (ffi_closure_fun)&_Jv_InterpMethod::run_normal_debug;
1409
          else
1410
            fun = (ffi_closure_fun)&_Jv_InterpMethod::run_normal;
1411
        }
1412
    }
1413
 
1414
  FFI_PREP_RAW_CLOSURE (&closure->closure,
1415
                        &closure->cif,
1416
                        fun,
1417
                        (void*)this,
1418
                        code);
1419
 
1420
  self->ncode = code;
1421
 
1422
  return self->ncode;
1423
}
1424
 
1425
/* Find the index of the given insn in the array of insn slots
1426
   for this method. Returns -1 if not found. */
1427
jlong
1428
_Jv_InterpMethod::insn_index (pc_t pc)
1429
{
1430
  jlong left = 0;
1431
#ifdef DIRECT_THREADED
1432
  jlong right = number_insn_slots;
1433
  pc_t insns = prepared;
1434
#else
1435
  jlong right = code_length;
1436
  pc_t insns = bytecode ();
1437
#endif
1438
 
1439
  while (right >= 0)
1440
    {
1441
      jlong mid = (left + right) / 2;
1442
      if (&insns[mid] == pc)
1443
        return mid;
1444
 
1445
      if (pc < &insns[mid])
1446
        right = mid - 1;
1447
      else
1448
        left = mid + 1;
1449
    }
1450
 
1451
  return -1;
1452
}
1453
 
1454
// Method to check if an exception is caught at some location in a method
1455
// (meth).  Returns true if this method (meth) contains a catch block for the
1456
// exception (ex). False otherwise.  If there is a catch block, it sets the pc
1457
// to the location of the beginning of the catch block.
1458
jboolean
1459
_Jv_InterpMethod::check_handler (pc_t *pc, _Jv_InterpMethod *meth,
1460
                                java::lang::Throwable *ex)
1461
{
1462
#ifdef DIRECT_THREADED
1463
  void *logical_pc = (void *) ((insn_slot *) (*pc) - 1);
1464
#else
1465
  int logical_pc = (*pc) - 1 - meth->bytecode ();
1466
#endif
1467
  _Jv_InterpException *exc = meth->exceptions ();
1468
  jclass exc_class = ex->getClass ();
1469
 
1470
  for (int i = 0; i < meth->exc_count; i++)
1471
    {
1472
      if (PCVAL (exc[i].start_pc) <= logical_pc
1473
          && logical_pc < PCVAL (exc[i].end_pc))
1474
        {
1475
#ifdef DIRECT_THREADED
1476
              jclass handler = (jclass) exc[i].handler_type.p;
1477
#else
1478
              jclass handler = NULL;
1479
              if (exc[i].handler_type.i != 0)
1480
                    handler
1481
                      = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
1482
                                             exc[i].handler_type.i)).clazz;
1483
#endif /* DIRECT_THREADED */
1484
              if (handler == NULL || handler->isAssignableFrom (exc_class))
1485
                {
1486
#ifdef DIRECT_THREADED
1487
                  (*pc) = (insn_slot *) exc[i].handler_pc.p;
1488
#else
1489
                  (*pc) = meth->bytecode () + exc[i].handler_pc.i;
1490
#endif /* DIRECT_THREADED */
1491
                  return true;
1492
                }
1493
          }
1494
      }
1495
  return false;
1496
}
1497
 
1498
 
1499
void
1500
_Jv_InterpMethod::get_line_table (jlong& start, jlong& end,
1501
                                  jintArray& line_numbers,
1502
                                  jlongArray& code_indices)
1503
{
1504
#ifdef DIRECT_THREADED
1505
  /* For the DIRECT_THREADED case, if the method has not yet been
1506
   * compiled, the linetable will change to insn slots instead of
1507
   * bytecode PCs. It is probably easiest, in this case, to simply
1508
   * compile the method and guarantee that we are using insn
1509
   * slots.
1510
   */
1511
  _Jv_CompileMethod (this);
1512
 
1513
  if (line_table_len > 0)
1514
    {
1515
      start = 0;
1516
      end = number_insn_slots;
1517
      line_numbers = JvNewIntArray (line_table_len);
1518
      code_indices = JvNewLongArray (line_table_len);
1519
 
1520
      jint* lines = elements (line_numbers);
1521
      jlong* indices = elements (code_indices);
1522
      for (int i = 0; i < line_table_len; ++i)
1523
        {
1524
          lines[i] = line_table[i].line;
1525
          indices[i] = insn_index (line_table[i].pc);
1526
        }
1527
    }
1528
#else // !DIRECT_THREADED
1529
  if (line_table_len > 0)
1530
    {
1531
      start = 0;
1532
      end = code_length;
1533
      line_numbers = JvNewIntArray (line_table_len);
1534
      code_indices = JvNewLongArray (line_table_len);
1535
 
1536
      jint* lines = elements (line_numbers);
1537
      jlong* indices = elements (code_indices);
1538
      for (int i = 0; i < line_table_len; ++i)
1539
        {
1540
          lines[i] = line_table[i].line;
1541
          indices[i] = (jlong) line_table[i].bytecode_pc;
1542
        }
1543
    }
1544
#endif // !DIRECT_THREADED
1545
}
1546
 
1547
int
1548
_Jv_InterpMethod::get_local_var_table (char **name, char **sig,
1549
                                       char **generic_sig, jlong *startloc,
1550
                                       jint *length, jint *slot,
1551
                                       int table_slot)
1552
{
1553
#ifdef DIRECT_THREADED
1554
  _Jv_CompileMethod (this);
1555
#endif
1556
 
1557
  if (local_var_table == NULL)
1558
    return -2;
1559
  if (table_slot >= local_var_table_len)
1560
    return -1;
1561
  else
1562
    {
1563
      *name = local_var_table[table_slot].name;
1564
      *sig = local_var_table[table_slot].descriptor;
1565
      *generic_sig = local_var_table[table_slot].descriptor;
1566
 
1567
#ifdef DIRECT_THREADED
1568
      *startloc = insn_index (local_var_table[table_slot].pc);
1569
#else
1570
      *startloc = static_cast<jlong> (local_var_table[table_slot].bytecode_pc);
1571
#endif
1572
      *length = static_cast<jint> (local_var_table[table_slot].length);
1573
      *slot = static_cast<jint> (local_var_table[table_slot].slot);
1574
    }
1575
  return local_var_table_len - table_slot - 1;
1576
}
1577
 
1578
pc_t
1579
_Jv_InterpMethod::install_break (jlong index)
1580
{
1581
  return set_insn (index, breakpoint_insn);
1582
}
1583
 
1584
pc_t
1585
_Jv_InterpMethod::get_insn (jlong index)
1586
{
1587
  pc_t code;
1588
 
1589
#ifdef DIRECT_THREADED
1590
  if (index >= number_insn_slots || index < 0)
1591
    return NULL;
1592
 
1593
  code = prepared;
1594
#else // !DIRECT_THREADED
1595
  if (index >= code_length || index < 0)
1596
    return NULL;
1597
 
1598
  code = reinterpret_cast<pc_t> (bytecode ());
1599
#endif // !DIRECT_THREADED
1600
 
1601
  return &code[index];
1602
}
1603
 
1604
pc_t
1605
_Jv_InterpMethod::set_insn (jlong index, pc_t insn)
1606
{
1607
#ifdef DIRECT_THREADED
1608
  if (index >= number_insn_slots || index < 0)
1609
    return NULL;
1610
 
1611
  pc_t code = prepared;
1612
  code[index].insn = insn->insn;
1613
#else // !DIRECT_THREADED
1614
  if (index >= code_length || index < 0)
1615
    return NULL;
1616
 
1617
  pc_t code = reinterpret_cast<pc_t> (bytecode ());
1618
  code[index] = *insn;
1619
#endif // !DIRECT_THREADED
1620
 
1621
  return &code[index];
1622
}
1623
 
1624
bool
1625
_Jv_InterpMethod::breakpoint_at (jlong index)
1626
{
1627
  pc_t insn = get_insn (index);
1628
  if (insn != NULL)
1629
    {
1630
#ifdef DIRECT_THREADED
1631
      return (insn->insn == breakpoint_insn->insn);
1632
#else
1633
      pc_t code = reinterpret_cast<pc_t> (bytecode ());
1634
      return (code[index] == bp_insn_opcode);
1635
#endif
1636
    }
1637
 
1638
  return false;
1639
}
1640
 
1641
void *
1642
_Jv_JNIMethod::ncode (jclass klass)
1643
{
1644
  using namespace java::lang::reflect;
1645
 
1646
  if (self->ncode != 0)
1647
    return self->ncode;
1648
 
1649
  jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
1650
  int arg_count = _Jv_count_arguments (self->signature, staticp);
1651
 
1652
  void *code;
1653
  ncode_closure *closure =
1654
    (ncode_closure*)ffi_closure_alloc (sizeof (ncode_closure)
1655
                                       + arg_count * sizeof (ffi_type*),
1656
                                       &code);
1657
  closure->list.registerClosure (klass, closure);
1658
 
1659
  ffi_type *rtype;
1660
  _Jv_init_cif (self->signature,
1661
                arg_count,
1662
                staticp,
1663
                &closure->cif,
1664
                &closure->arg_types[0],
1665
                &rtype);
1666
 
1667
  ffi_closure_fun fun;
1668
 
1669
  args_raw_size = FFI_RAW_SIZE (&closure->cif);
1670
 
1671
  // Initialize the argument types and CIF that represent the actual
1672
  // underlying JNI function.
1673
  int extra_args = 1;
1674
  if ((self->accflags & Modifier::STATIC))
1675
    ++extra_args;
1676
  jni_arg_types = (ffi_type **) _Jv_AllocBytes ((extra_args + arg_count)
1677
                                                * sizeof (ffi_type *));
1678
  int offset = 0;
1679
  jni_arg_types[offset++] = &ffi_type_pointer;
1680
  if ((self->accflags & Modifier::STATIC))
1681
    jni_arg_types[offset++] = &ffi_type_pointer;
1682
  memcpy (&jni_arg_types[offset], &closure->arg_types[0],
1683
          arg_count * sizeof (ffi_type *));
1684
 
1685
  if (ffi_prep_cif (&jni_cif, _Jv_platform_ffi_abi,
1686
                    extra_args + arg_count, rtype,
1687
                    jni_arg_types) != FFI_OK)
1688
    throw_internal_error ("ffi_prep_cif failed for JNI function");
1689
 
1690
  JvAssert ((self->accflags & Modifier::NATIVE) != 0);
1691
 
1692
  // FIXME: for now we assume that all native methods for
1693
  // interpreted code use JNI.
1694
  fun = (ffi_closure_fun) &_Jv_JNIMethod::call;
1695
 
1696
  FFI_PREP_RAW_CLOSURE (&closure->closure,
1697
                        &closure->cif,
1698
                        fun,
1699
                        (void*) this,
1700
                        code);
1701
 
1702
  self->ncode = code;
1703
  return self->ncode;
1704
}
1705
 
1706
static void
1707
throw_class_format_error (jstring msg)
1708
{
1709
  jthrowable t = (msg
1710
         ? new java::lang::ClassFormatError (msg)
1711
         : new java::lang::ClassFormatError);
1712
  REPORT_EXCEPTION (t);
1713
  throw t;
1714
}
1715
 
1716
static void
1717
throw_class_format_error (const char *msg)
1718
{
1719
  throw_class_format_error (JvNewStringLatin1 (msg));
1720
}
1721
 
1722
/* This function finds the method and location where the exception EXC
1723
   is caught in the stack frame. On return, it sets CATCH_METHOD and
1724
   CATCH_LOCATION with the method and location where the catch will
1725
   occur. If the exception is not caught, these are set to 0.
1726
 
1727
   This function should only be used with the __GCJ_DEBUG interpreter. */
1728
static void
1729
find_catch_location (::java::lang::Throwable *exc, jthread thread,
1730
                     jmethodID *catch_method, jlong *catch_loc)
1731
{
1732
  *catch_method = 0;
1733
  *catch_loc = 0;
1734
 
1735
  _Jv_InterpFrame *frame
1736
    = reinterpret_cast<_Jv_InterpFrame *> (thread->interp_frame);
1737
  while (frame != NULL)
1738
    {
1739
      pc_t pc = frame->get_pc ();
1740
      _Jv_InterpMethod *imeth
1741
        = reinterpret_cast<_Jv_InterpMethod *> (frame->self);
1742
      if (imeth->check_handler (&pc, imeth, exc))
1743
        {
1744
          // This method handles the exception.
1745
          *catch_method = imeth->get_method ();
1746
          *catch_loc = imeth->insn_index (pc);
1747
          return;
1748
        }
1749
 
1750
      frame = frame->next_interp;
1751
    }
1752
}
1753
 
1754
/* This method handles JVMTI notifications of thrown exceptions. It
1755
   calls find_catch_location to figure out where the exception is
1756
   caught (if it is caught).
1757
 
1758
   Like find_catch_location, this should only be called with the
1759
   __GCJ_DEBUG interpreter. Since a few exceptions occur outside the
1760
   interpreter proper, it is important to not call this function
1761
   without checking JVMTI_REQUESTED_EVENT(Exception) first. */
1762
void
1763
_Jv_ReportJVMTIExceptionThrow (jthrowable ex)
1764
{
1765
  jthread thread = ::java::lang::Thread::currentThread ();
1766
  _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
1767
  jmethodID throw_meth = frame->self->get_method ();
1768
  jlocation throw_loc = -1;
1769
  if (frame->frame_type == frame_interpreter)
1770
    {
1771
      _Jv_InterpFrame * iframe
1772
        = reinterpret_cast<_Jv_InterpFrame *> (frame);
1773
      _Jv_InterpMethod *imeth
1774
        = reinterpret_cast<_Jv_InterpMethod *> (frame->self);
1775
      throw_loc = imeth->insn_index (iframe->get_pc ());
1776
    }
1777
 
1778
  jlong catch_loc;
1779
  jmethodID catch_method;
1780
  find_catch_location (ex, thread, &catch_method, &catch_loc);
1781
  _Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION, thread,
1782
                       _Jv_GetCurrentJNIEnv (), throw_meth, throw_loc,
1783
                       ex, catch_method, catch_loc);
1784
}
1785
 
1786
 
1787
 
1788
void
1789
_Jv_InterpreterEngine::do_verify (jclass klass)
1790
{
1791
  _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1792
  for (int i = 0; i < klass->method_count; i++)
1793
    {
1794
      using namespace java::lang::reflect;
1795
      _Jv_MethodBase *imeth = iclass->interpreted_methods[i];
1796
      _Jv_ushort accflags = klass->methods[i].accflags;
1797
      if ((accflags & (Modifier::NATIVE | Modifier::ABSTRACT)) == 0)
1798
        {
1799
          _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
1800
          _Jv_VerifyMethod (im);
1801
        }
1802
    }
1803
}
1804
 
1805
void
1806
_Jv_InterpreterEngine::do_create_ncode (jclass klass)
1807
{
1808
  _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1809
  for (int i = 0; i < klass->method_count; i++)
1810
    {
1811
      // Just skip abstract methods.  This is particularly important
1812
      // because we don't resize the interpreted_methods array when
1813
      // miranda methods are added to it.
1814
      if ((klass->methods[i].accflags
1815
           & java::lang::reflect::Modifier::ABSTRACT)
1816
          != 0)
1817
        continue;
1818
 
1819
      _Jv_MethodBase *imeth = iclass->interpreted_methods[i];
1820
 
1821
      if ((klass->methods[i].accflags & java::lang::reflect::Modifier::NATIVE)
1822
          != 0)
1823
        {
1824
          // You might think we could use a virtual `ncode' method in
1825
          // the _Jv_MethodBase and unify the native and non-native
1826
          // cases.  Well, we can't, because we don't allocate these
1827
          // objects using `new', and thus they don't get a vtable.
1828
          _Jv_JNIMethod *jnim = reinterpret_cast<_Jv_JNIMethod *> (imeth);
1829
          klass->methods[i].ncode = jnim->ncode (klass);
1830
        }
1831
      else if (imeth != 0)               // it could be abstract
1832
        {
1833
          _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
1834
          klass->methods[i].ncode = im->ncode (klass);
1835
        }
1836
    }
1837
}
1838
 
1839
_Jv_ClosureList **
1840
_Jv_InterpreterEngine::do_get_closure_list (jclass klass)
1841
{
1842
  _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1843
 
1844
  if (!iclass->closures)
1845
    iclass->closures = _Jv_ClosureListFinalizer ();
1846
 
1847
  return iclass->closures;
1848
}
1849
 
1850
void
1851
_Jv_InterpreterEngine::do_allocate_static_fields (jclass klass,
1852
                                                  int pointer_size,
1853
                                                  int other_size)
1854
{
1855
  _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1856
 
1857
  // Splitting the allocations here lets us scan reference fields and
1858
  // avoid scanning non-reference fields.  How reference fields are
1859
  // scanned is a bit tricky: we allocate using _Jv_AllocRawObj, which
1860
  // means that this memory will be scanned conservatively (same
1861
  // difference, since we know all the contents here are pointers).
1862
  // Then we put pointers into this memory into the 'fields'
1863
  // structure.  Most of these are interior pointers, which is ok (but
1864
  // even so the pointer to the first reference field will be used and
1865
  // that is not an interior pointer).  The 'fields' array is also
1866
  // allocated with _Jv_AllocRawObj (see defineclass.cc), so it will
1867
  // be scanned.  A pointer to this array is held by Class and thus
1868
  // seen by the collector.
1869
  char *reference_fields = (char *) _Jv_AllocRawObj (pointer_size);
1870
  char *non_reference_fields = (char *) _Jv_AllocBytes (other_size);
1871
 
1872
  for (int i = 0; i < klass->field_count; i++)
1873
    {
1874
      _Jv_Field *field = &klass->fields[i];
1875
 
1876
      if ((field->flags & java::lang::reflect::Modifier::STATIC) == 0)
1877
        continue;
1878
 
1879
      char *base = field->isRef() ? reference_fields : non_reference_fields;
1880
      field->u.addr  = base + field->u.boffset;
1881
 
1882
      if (iclass->field_initializers[i] != 0)
1883
        {
1884
          _Jv_Linker::resolve_field (field, klass->loader);
1885
          _Jv_InitField (0, klass, i);
1886
        }
1887
    }
1888
 
1889
  // Now we don't need the field_initializers anymore, so let the
1890
  // collector get rid of it.
1891
  iclass->field_initializers = 0;
1892
}
1893
 
1894
_Jv_ResolvedMethod *
1895
_Jv_InterpreterEngine::do_resolve_method (_Jv_Method *method, jclass klass,
1896
                                          jboolean staticp)
1897
{
1898
  int arg_count = _Jv_count_arguments (method->signature, staticp);
1899
 
1900
  _Jv_ResolvedMethod* result = (_Jv_ResolvedMethod*)
1901
    _Jv_AllocBytes (sizeof (_Jv_ResolvedMethod)
1902
                    + arg_count*sizeof (ffi_type*));
1903
 
1904
  result->stack_item_count
1905
    = _Jv_init_cif (method->signature,
1906
                    arg_count,
1907
                    staticp,
1908
                    &result->cif,
1909
                    &result->arg_types[0],
1910
                    NULL);
1911
 
1912
  result->method              = method;
1913
  result->klass               = klass;
1914
 
1915
  return result;
1916
}
1917
 
1918
void
1919
_Jv_InterpreterEngine::do_post_miranda_hook (jclass klass)
1920
{
1921
  _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1922
  for (int i = 0; i < klass->method_count; i++)
1923
    {
1924
      // Just skip abstract methods.  This is particularly important
1925
      // because we don't resize the interpreted_methods array when
1926
      // miranda methods are added to it.
1927
      if ((klass->methods[i].accflags
1928
           & java::lang::reflect::Modifier::ABSTRACT)
1929
          != 0)
1930
        continue;
1931
      // Miranda method additions mean that the `methods' array moves.
1932
      // We cache a pointer into this array, so we have to update.
1933
      iclass->interpreted_methods[i]->self = &klass->methods[i];
1934
    }
1935
}
1936
 
1937
#ifdef DIRECT_THREADED
1938
void
1939
_Jv_CompileMethod (_Jv_InterpMethod* method)
1940
{
1941
  if (method->prepared == NULL)
1942
    {
1943
      if (JVMTI::enabled)
1944
        _Jv_InterpMethod::run_debug (NULL, NULL, method);
1945
      else
1946
      _Jv_InterpMethod::run (NULL, NULL, method);
1947
    }
1948
}
1949
#endif // DIRECT_THREADED

powered by: WebSVN 2.1.0

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