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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [include/] [java-interp.h] - Blame information for rev 867

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

Line No. Rev Author Line
1 757 jeremybenn
// java-interp.h - Header file for the bytecode interpreter.  -*- c++ -*-
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
#ifndef __JAVA_INTERP_H__
12
#define __JAVA_INTERP_H__
13
 
14
#include <jvm.h>
15
#include <java-cpool.h>
16
#include <gnu/gcj/runtime/NameFinder.h>
17
 
18
enum _Jv_FrameType
19
{
20
  frame_native,
21
  frame_interpreter,
22
  frame_proxy
23
};
24
 
25
#ifdef INTERPRETER
26
 
27
#pragma interface
28
 
29
#include <java/lang/Class.h>
30
#include <java/lang/ClassLoader.h>
31
#include <java/lang/reflect/Modifier.h>
32
#include <java/lang/Thread.h>
33
#include <gnu/gcj/RawData.h>
34
 
35
// Define this to get the direct-threaded interpreter.  If undefined,
36
// we revert to a basic bytecode interpreter.  The former is faster
37
// but uses more memory.
38
#define DIRECT_THREADED
39
 
40
#include <ffi.h>
41
 
42
struct _Jv_ResolvedMethod;
43
 
44
void _Jv_InitInterpreter ();
45
void _Jv_DefineClass (jclass, jbyteArray, jint, jint,
46
                      java::security::ProtectionDomain *,
47
                      _Jv_Utf8Const **);
48
 
49
void _Jv_InitField (jobject, jclass, int);
50
void * _Jv_AllocMethodInvocation (jsize size);
51
int  _Jv_count_arguments (_Jv_Utf8Const *signature,
52
                          jboolean staticp = true);
53
void _Jv_VerifyMethod (_Jv_InterpMethod *method);
54
void _Jv_CompileMethod (_Jv_InterpMethod* method);
55
int _Jv_init_cif (_Jv_Utf8Const* signature,
56
                  int arg_count,
57
                  jboolean staticp,
58
                  ffi_cif *cif,
59
                  ffi_type **arg_types,
60
                  ffi_type **rtype_p);
61
 
62
/* the interpreter is written in C++, primarily because it makes it easy for
63
 * the entire thing to be "friend" with class Class. */
64
 
65
class _Jv_InterpClass;
66
class _Jv_InterpMethod;
67
 
68
// Before a method is "compiled" we store values as the bytecode PC,
69
// an int.  Afterwards we store them as pointers into the prepared
70
// code itself.
71
union _Jv_InterpPC
72
{
73
  int i;
74
  void *p;
75
};
76
 
77
class _Jv_InterpException
78
{
79
  _Jv_InterpPC start_pc;
80
  _Jv_InterpPC end_pc;
81
  _Jv_InterpPC handler_pc;
82
  _Jv_InterpPC handler_type;
83
 
84
  friend class _Jv_ClassReader;
85
  friend class _Jv_InterpMethod;
86
  friend class _Jv_BytecodeVerifier;
87
};
88
 
89
// Base class for method representations.  Subclasses are interpreted
90
// and JNI methods.
91
class _Jv_MethodBase
92
{
93
protected:
94
  // The class which defined this method.
95
  jclass defining_class;
96
 
97
  // The method description.
98
  _Jv_Method *self;
99
 
100
  // Size of raw arguments.
101
  _Jv_ushort args_raw_size;
102
 
103
  friend class _Jv_InterpreterEngine;
104
 
105
public:
106
  _Jv_Method *get_method ()
107
  {
108
    return self;
109
  }
110
};
111
 
112
// The type of the PC depends on whether we're doing direct threading
113
// or a more ordinary bytecode interpreter.
114
#ifdef DIRECT_THREADED
115
// Slot in the "compiled" form of the bytecode.
116
union insn_slot
117
{
118
  // Address of code.
119
  void *insn;
120
  // An integer value used by an instruction.
121
  jint int_val;
122
  // A pointer value used by an instruction.
123
  void *datum;
124
};
125
 
126
typedef insn_slot *pc_t;
127
#else
128
typedef unsigned char *pc_t;
129
#endif
130
 
131
 
132
// This structure holds the bytecode pc and corresponding source code
133
// line number.  An array (plus length field) of this structure is put
134
// in each _Jv_InterpMethod and used to resolve the (internal) program
135
// counter of the interpreted method to an actual java source file
136
// line.
137
struct  _Jv_LineTableEntry
138
{
139
  union
140
  {
141
    pc_t pc;
142
    int bytecode_pc;
143
  };
144
  int line;
145
};
146
 
147
// This structure holds local variable information.
148
// Like _Jv_LineTableEntry above, it is remapped when the method is
149
// compiled for direct threading.
150
struct _Jv_LocalVarTableEntry
151
{
152
  // First PC value at which variable is live
153
  union
154
  {
155
    pc_t pc;
156
    int bytecode_pc;
157
  };
158
 
159
  // length of visibility of variable
160
  int length;
161
 
162
  // variable name
163
  char *name;
164
 
165
  // type description
166
  char *descriptor;
167
 
168
  // stack slot number (long and double occupy slot and slot + 1)
169
  int slot;
170
};
171
 
172
class _Jv_InterpMethod : public _Jv_MethodBase
173
{
174
  // Breakpoint instruction
175
  static pc_t breakpoint_insn;
176
#ifdef DIRECT_THREADED
177
  static insn_slot bp_insn_slot;
178
 
179
public:
180
  // Mutex to prevent a data race between threads when rewriting
181
  // instructions.  See interpret-run.cc for an explanation of its use.
182
  static _Jv_Mutex_t rewrite_insn_mutex;
183
 
184
  // The count of threads executing this method.
185
  long thread_count;
186
 
187
private:
188
 
189
#else
190
  static unsigned char bp_insn_opcode;
191
#endif
192
 
193
  _Jv_ushort       max_stack;
194
  _Jv_ushort       max_locals;
195
  int              code_length;
196
 
197
  _Jv_ushort       exc_count;
198
  bool             is_15;
199
 
200
  // Length of the line_table - when this is zero then line_table is NULL.
201
  int line_table_len;
202
  _Jv_LineTableEntry *line_table;
203
 
204
  // The local variable table length and the table itself
205
  int local_var_table_len;
206
  _Jv_LocalVarTableEntry *local_var_table;
207
 
208
  pc_t prepared;
209
  int number_insn_slots;
210
 
211
  unsigned char* bytecode ()
212
  {
213
    return
214
      ((unsigned char*)this)
215
      + ROUND((sizeof (_Jv_InterpMethod)
216
               + exc_count*sizeof (_Jv_InterpException)), 4);
217
  }
218
 
219
  _Jv_InterpException * exceptions ()
220
  {
221
    return (_Jv_InterpException*) (this+1);
222
  }
223
 
224
  static size_t size (int exc_count, int code_length)
225
  {
226
    return
227
      ROUND ((sizeof (_Jv_InterpMethod)
228
              + (exc_count * sizeof (_Jv_InterpException))), 4)
229
      + code_length;
230
  }
231
 
232
  // return the method's invocation pointer (a stub).
233
  void *ncode (jclass);
234
  void compile (const void * const *);
235
 
236
#if FFI_NATIVE_RAW_API
237
#  define INTERP_FFI_RAW_TYPE ffi_raw
238
#else
239
#  define INTERP_FFI_RAW_TYPE ffi_java_raw
240
#endif
241
 
242
  static void run_normal (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
243
  static void run_synch_object (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
244
  static void run_class (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
245
  static void run_synch_class (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
246
 
247
  static void run_normal_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
248
  static void run_synch_object_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*,
249
                                      void*);
250
  static void run_class_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
251
  static void run_synch_class_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*,
252
                                     void*);
253
 
254
  static void run (void *, INTERP_FFI_RAW_TYPE *, _Jv_InterpMethod *);
255
  static void run_debug (void *, INTERP_FFI_RAW_TYPE *, _Jv_InterpMethod *);
256
 
257
 
258
 
259
  // Returns source file line number for given PC value, or -1 if line
260
  // number info is unavailable.
261
  int get_source_line(pc_t mpc);
262
 
263
   public:
264
 
265
  // Convenience function for indexing bytecode PC/insn slots in
266
  // line tables for JDWP
267
  jlong insn_index (pc_t pc);
268
 
269
  // Helper function used to check if there is a handler for an exception
270
  // present at this code index
271
  jboolean check_handler (pc_t *pc, _Jv_InterpMethod *meth,
272
                     java::lang::Throwable *ex);
273
 
274
  /* Get the line table for this method.
275
   * start  is the lowest index in the method
276
   * end    is the  highest index in the method
277
   * line_numbers is an array to hold the list of source line numbers
278
   * code_indices is an array to hold the corresponding list of code indices
279
   */
280
  void get_line_table (jlong& start, jlong& end, jintArray& line_numbers,
281
                       jlongArray& code_indices);
282
 
283
  int get_max_locals ()
284
  {
285
    return static_cast<int> (max_locals);
286
  }
287
 
288
  /* Get info for a local variable of this method.
289
   * If there is no loca_var_table for this method it will return -1.
290
   * table_slot  indicates which slot in the local_var_table to get, if there is
291
   * no variable at this location it will return 0.
292
   * Otherwise, it will return the number of table slots after the selected
293
   * slot, indexed from 0.
294
   *
295
   * Example: there are 5 slots in the table, you request slot 0 so it will
296
   * return 4.
297
   */
298
  int get_local_var_table (char **name, char **sig, char **generic_sig,
299
                           jlong *startloc, jint *length, jint *slot,
300
                           int table_slot);
301
 
302
  /* Installs a break instruction at the given code index. Returns
303
     the pc_t of the breakpoint or NULL if index is invalid. */
304
  pc_t install_break (jlong index);
305
 
306
  // Gets the instruction at the given index
307
  pc_t get_insn (jlong index);
308
 
309
  /* Writes the given instruction at the given code index. Returns
310
     the insn or NULL if index is invalid. */
311
  pc_t set_insn (jlong index, pc_t insn);
312
 
313
  // Is the given location in this method a breakpoint?
314
  bool breakpoint_at (jlong index);
315
 
316
#ifdef DIRECT_THREADED
317
  friend void _Jv_CompileMethod (_Jv_InterpMethod*);
318
#endif
319
 
320
  friend class _Jv_ClassReader;
321
  friend class _Jv_BytecodeVerifier;
322
  friend class _Jv_StackTrace;
323
  friend class _Jv_InterpreterEngine;
324
 
325
#ifdef JV_MARKOBJ_DECL
326
  friend JV_MARKOBJ_DECL;
327
#endif
328
};
329
 
330
class _Jv_InterpClass
331
{
332
  _Jv_MethodBase **interpreted_methods;
333
  _Jv_ushort     *field_initializers;
334
  jstring source_file_name;
335
  _Jv_ClosureList **closures;
336
 
337
  friend class _Jv_ClassReader;
338
  friend class _Jv_InterpMethod;
339
  friend class _Jv_StackTrace;
340
  friend class _Jv_InterpreterEngine;
341
 
342
  friend void  _Jv_InitField (jobject, jclass, int);
343
#ifdef JV_MARKOBJ_DECL
344
  friend JV_MARKOBJ_DECL;
345
#endif
346
 
347
  friend _Jv_MethodBase ** _Jv_GetFirstMethod (_Jv_InterpClass *klass);
348
  friend jstring _Jv_GetInterpClassSourceFile (jclass);
349
};
350
 
351
extern inline _Jv_MethodBase **
352
_Jv_GetFirstMethod (_Jv_InterpClass *klass)
353
{
354
  return klass->interpreted_methods;
355
}
356
 
357
struct _Jv_ResolvedMethod
358
{
359
  jint            stack_item_count;
360
  jclass          klass;
361
  _Jv_Method*     method;
362
 
363
  // a resolved method holds the cif in-line, so that _Jv_MarkObj just needs
364
  // to mark the resolved method to hold on to the cif.  Some memory could be
365
  // saved by keeping a cache of cif's, since many will be the same.
366
  ffi_cif         cif;
367
  ffi_type *      arg_types[0];
368
};
369
 
370
class _Jv_JNIMethod : public _Jv_MethodBase
371
{
372
  // The underlying function.  If NULL we have to look for the
373
  // function.
374
  void *function;
375
 
376
  // This is the CIF used by the JNI function.
377
  ffi_cif jni_cif;
378
 
379
  // These are the argument types used by the JNI function.
380
  ffi_type **jni_arg_types;
381
 
382
  // This function is used when making a JNI call from the interpreter.
383
  static void call (ffi_cif *, void *, INTERP_FFI_RAW_TYPE *, void *);
384
 
385
  void *ncode (jclass);
386
 
387
  friend class _Jv_ClassReader;
388
  friend class _Jv_InterpreterEngine;
389
 
390
#ifdef JV_MARKOBJ_DECL
391
  friend JV_MARKOBJ_DECL;
392
#endif
393
 
394
public:
395
  // FIXME: this is ugly.
396
  void set_function (void *f)
397
  {
398
    function = f;
399
  }
400
};
401
 
402
//  The composite call stack as represented by a linked list of frames
403
class _Jv_Frame
404
{
405
public:
406
  java::lang::Thread *thread;
407
 
408
  union
409
  {
410
    _Jv_MethodBase *self;
411
    void *meth;
412
    _Jv_Method *proxyMethod;
413
  };
414
 
415
  //The full list of frames, JNI and interpreted
416
  _Jv_Frame *next;
417
  _Jv_FrameType frame_type;
418
 
419
  _Jv_Frame (_Jv_MethodBase *s, java::lang::Thread *thr, _Jv_FrameType type)
420
  {
421
    self = s;
422
    frame_type = type;
423
    next = (_Jv_Frame *) thr->frame;
424
    thr->frame = (gnu::gcj::RawData *) this;
425
    thread = thr;
426
  }
427
 
428
  ~_Jv_Frame ()
429
  {
430
    thread->frame = (gnu::gcj::RawData *) next;
431
  }
432
 
433
  int depth ()
434
  {
435
    int depth = 0;
436
    struct _Jv_Frame *f;
437
    for (f = this; f != NULL; f = f->next)
438
      ++depth;
439
 
440
    return depth;
441
  }
442
};
443
 
444
// An interpreted frame in the call stack
445
class _Jv_InterpFrame : public _Jv_Frame
446
{
447
public:
448
 
449
  // Keep the purely interpreted list around so as not to break backtraces
450
  _Jv_InterpFrame *next_interp;
451
 
452
  union
453
  {
454
    pc_t pc;
455
    jclass proxyClass;
456
  };
457
 
458
  // Pointer to the actual pc value.
459
  pc_t *pc_ptr;
460
 
461
  //Debug info for local variables.
462
  _Jv_word *locals;
463
  char *locals_type;
464
 
465
  // Object pointer for this frame ("this")
466
  jobject obj_ptr;
467
 
468
  _Jv_InterpFrame (void *meth, java::lang::Thread *thr, jclass proxyCls = NULL,
469
                   pc_t *pc = NULL,
470
                   _Jv_FrameType frame_type = frame_interpreter)
471
  : _Jv_Frame (reinterpret_cast<_Jv_MethodBase *> (meth), thr,
472
                     frame_type)
473
  {
474
    next_interp = (_Jv_InterpFrame *) thr->interp_frame;
475
    proxyClass = proxyCls;
476
    thr->interp_frame = (gnu::gcj::RawData *) this;
477
    obj_ptr = NULL;
478
    pc_ptr = pc;
479
  }
480
 
481
  ~_Jv_InterpFrame ()
482
  {
483
    thread->interp_frame = (gnu::gcj::RawData *) next_interp;
484
  }
485
 
486
  jobject get_this_ptr ()
487
  {
488
    return obj_ptr;
489
  }
490
 
491
  pc_t get_pc ()
492
  {
493
    pc_t pc;
494
 
495
    // If the PC_PTR is NULL, we are not debugging.
496
    if (pc_ptr == NULL)
497
      pc = 0;
498
    else
499
      pc = *pc_ptr - 1;
500
 
501
    return pc;
502
  }
503
};
504
 
505
// A native frame in the call stack really just a placeholder
506
class _Jv_NativeFrame : public _Jv_Frame
507
{
508
public:
509
 
510
  _Jv_NativeFrame (_Jv_JNIMethod *s, java::lang::Thread *thr)
511
  : _Jv_Frame (s, thr, frame_native)
512
  {
513
  }
514
};
515
 
516
#ifdef DIRECT_THREADED
517
// This class increments and decrements the thread_count field in an
518
// interpreted method.  On entry to the interpreter a
519
// ThreadCountAdjuster is created when increments the thread_count in
520
// the current method and uses the next_interp field in the frame to
521
// find the previous method and decrement its thread_count.
522
class ThreadCountAdjuster
523
{
524
 
525
  // A class used to handle the rewrite_insn_mutex while we're
526
  // adjusting the thread_count in a method.  Unlocking the mutex in a
527
  // destructor ensures that it's unlocked even if (for example) a
528
  // segfault occurs in the critical section.
529
  class MutexLock
530
  {
531
  private:
532
    _Jv_Mutex_t *mutex;
533
  public:
534
    MutexLock (_Jv_Mutex_t *m)
535
    {
536
      mutex = m;
537
      _Jv_MutexLock (mutex);
538
    }
539
    ~MutexLock ()
540
    {
541
      _Jv_MutexUnlock (mutex);
542
    }
543
  };
544
 
545
  _Jv_InterpMethod *method;
546
  _Jv_InterpMethod *next_method;
547
 
548
public:
549
 
550
  ThreadCountAdjuster (_Jv_InterpMethod *m, _Jv_InterpFrame *fr)
551
  {
552
    MutexLock lock (&::_Jv_InterpMethod::rewrite_insn_mutex);
553
 
554
    method = m;
555
    next_method = NULL;
556
 
557
    _Jv_InterpFrame *next_interp = fr->next_interp;
558
 
559
    // Record the fact that we're executing this method and that
560
    // we're no longer executing the method that called us.
561
    method->thread_count++;
562
 
563
    if (next_interp && next_interp->frame_type == frame_interpreter)
564
      {
565
        next_method
566
          = reinterpret_cast<_Jv_InterpMethod *> (next_interp->meth);
567
        next_method->thread_count--;
568
      }
569
  }
570
 
571
  ~ThreadCountAdjuster ()
572
  {
573
    MutexLock lock (&::_Jv_InterpMethod::rewrite_insn_mutex);
574
 
575
    // We're going to return to the method that called us, so bump its
576
    // thread_count and decrement our own.
577
 
578
    method->thread_count--;
579
 
580
    if (next_method)
581
      next_method->thread_count++;
582
  }
583
};
584
#endif // DIRECT_THREADED
585
 
586
#endif /* INTERPRETER */
587
 
588
#endif /* __JAVA_INTERP_H__ */

powered by: WebSVN 2.1.0

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