mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			277 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			277 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
// execution.h - Execution engines. -*- c++ -*-
 | 
						|
 | 
						|
/* Copyright (C) 2004, 2006, 2007  Free Software Foundation
 | 
						|
 | 
						|
   This file is part of libgcj.
 | 
						|
 | 
						|
This software is copyrighted work licensed under the terms of the
 | 
						|
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 | 
						|
details.  */
 | 
						|
 | 
						|
#ifndef __JAVA_EXECUTION_H__
 | 
						|
#define __JAVA_EXECUTION_H__
 | 
						|
 | 
						|
// This represents one execution engine.  Note that we use function
 | 
						|
// pointers and not virtual methods to avoid calls to
 | 
						|
// __cxa_call_unexpected and the like.
 | 
						|
struct _Jv_ExecutionEngine
 | 
						|
{
 | 
						|
 public:
 | 
						|
 | 
						|
  void (*unregister) (jclass);
 | 
						|
  // FIXME: probably should handle this elsewhere, see how
 | 
						|
  // interpreter does it.
 | 
						|
  bool (*need_resolve_string_fields) ();
 | 
						|
  void (*verify) (jclass);
 | 
						|
  void (*allocate_static_fields) (jclass, int, int);
 | 
						|
  void (*allocate_field_initializers) (jclass);
 | 
						|
  void (*create_ncode) (jclass);
 | 
						|
  _Jv_ResolvedMethod *(*resolve_method) (_Jv_Method *, jclass,
 | 
						|
					 jboolean);
 | 
						|
  void (*post_miranda_hook) (jclass);
 | 
						|
  _Jv_ClosureList **(*get_closure_list) (jclass);
 | 
						|
};
 | 
						|
 | 
						|
// This handles gcj-compiled code except that compiled with
 | 
						|
// -findirect-classes.
 | 
						|
struct _Jv_CompiledEngine : public _Jv_ExecutionEngine
 | 
						|
{
 | 
						|
 public:
 | 
						|
 | 
						|
  static void do_unregister (jclass)
 | 
						|
  {
 | 
						|
  }
 | 
						|
 | 
						|
  static bool do_need_resolve_string_fields ()
 | 
						|
  {
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
  static void do_verify (jclass klass)
 | 
						|
  {
 | 
						|
    _Jv_Linker::verify_type_assertions (klass);
 | 
						|
  }
 | 
						|
 | 
						|
  static _Jv_ResolvedMethod *do_resolve_method (_Jv_Method *, jclass,
 | 
						|
						jboolean)
 | 
						|
  {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  static void do_allocate_static_fields (jclass,
 | 
						|
					 int,
 | 
						|
					 int)
 | 
						|
  {
 | 
						|
  }
 | 
						|
 | 
						|
  static void do_allocate_field_initializers (jclass)
 | 
						|
  {
 | 
						|
  }
 | 
						|
 | 
						|
  static void do_create_ncode (jclass)
 | 
						|
  {
 | 
						|
    // Not needed.
 | 
						|
  }
 | 
						|
 | 
						|
  static void do_post_miranda_hook (jclass)
 | 
						|
  {
 | 
						|
    // Not needed.
 | 
						|
  }
 | 
						|
 | 
						|
  static _Jv_ClosureList **do_get_closure_list (jclass)
 | 
						|
  {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  _Jv_CompiledEngine ()
 | 
						|
  {
 | 
						|
    unregister = do_unregister;
 | 
						|
    need_resolve_string_fields = do_need_resolve_string_fields;
 | 
						|
    verify = do_verify;
 | 
						|
    allocate_static_fields = do_allocate_static_fields;
 | 
						|
    allocate_field_initializers = do_allocate_field_initializers;
 | 
						|
    create_ncode = do_create_ncode;
 | 
						|
    resolve_method = do_resolve_method;
 | 
						|
    post_miranda_hook = do_post_miranda_hook;
 | 
						|
    get_closure_list = do_get_closure_list;
 | 
						|
  }
 | 
						|
 | 
						|
  // These operators make it so we don't have to link in libstdc++.
 | 
						|
  void *operator new (size_t bytes)
 | 
						|
  {
 | 
						|
    return _Jv_Malloc(bytes);
 | 
						|
  }
 | 
						|
 | 
						|
  void operator delete (void *mem)
 | 
						|
  {
 | 
						|
    _Jv_Free(mem);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
class _Jv_IndirectCompiledClass
 | 
						|
{
 | 
						|
public:
 | 
						|
  void **field_initializers;
 | 
						|
  _Jv_ClosureList **closures;
 | 
						|
};
 | 
						|
 | 
						|
// This handles gcj-compiled code compiled with -findirect-classes.
 | 
						|
struct _Jv_IndirectCompiledEngine : public _Jv_CompiledEngine
 | 
						|
{
 | 
						|
  _Jv_IndirectCompiledEngine () : _Jv_CompiledEngine ()
 | 
						|
  {
 | 
						|
    allocate_static_fields = do_allocate_static_fields;
 | 
						|
    allocate_field_initializers = do_allocate_field_initializers;
 | 
						|
    get_closure_list = do_get_closure_list;
 | 
						|
  }
 | 
						|
  
 | 
						|
  static _Jv_IndirectCompiledClass *get_aux_info (jclass klass)
 | 
						|
  {
 | 
						|
    _Jv_IndirectCompiledClass *aux =
 | 
						|
      (_Jv_IndirectCompiledClass*)klass->aux_info;
 | 
						|
    if (!aux)
 | 
						|
      {
 | 
						|
	aux = (_Jv_IndirectCompiledClass*)
 | 
						|
	  _Jv_AllocRawObj (sizeof (_Jv_IndirectCompiledClass));
 | 
						|
	klass->aux_info = aux;
 | 
						|
      }
 | 
						|
 | 
						|
    return aux;
 | 
						|
  }
 | 
						|
 | 
						|
  static void do_allocate_field_initializers (jclass klass)
 | 
						|
  {
 | 
						|
    _Jv_IndirectCompiledClass *aux = get_aux_info (klass);
 | 
						|
    if (!aux)
 | 
						|
      {
 | 
						|
	aux = (_Jv_IndirectCompiledClass*)
 | 
						|
	  _Jv_AllocRawObj (sizeof (_Jv_IndirectCompiledClass));
 | 
						|
	klass->aux_info = aux;
 | 
						|
      }
 | 
						|
 | 
						|
    aux->field_initializers = (void **)_Jv_Malloc (klass->field_count 
 | 
						|
						   * sizeof (void*));    
 | 
						|
 | 
						|
    for (int i = 0; i < klass->field_count; i++)
 | 
						|
      {
 | 
						|
	_Jv_Field *field = &klass->fields[i];
 | 
						|
	if (field->flags & java::lang::reflect::Modifier::STATIC)
 | 
						|
	  {
 | 
						|
	    aux->field_initializers[i] = field->u.addr;
 | 
						|
	    field->u.addr = NULL; 
 | 
						|
	  }
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  static void do_allocate_static_fields (jclass klass,
 | 
						|
					 int pointer_size,
 | 
						|
					 int other_size)
 | 
						|
  {
 | 
						|
    // Splitting the allocations here lets us scan reference fields
 | 
						|
    // and avoid scanning non-reference fields.
 | 
						|
    char *reference_fields = (char *) _Jv_AllocRawObj (pointer_size);
 | 
						|
    char *non_reference_fields = (char *) _Jv_AllocBytes (other_size);
 | 
						|
 | 
						|
    _Jv_IndirectCompiledClass *aux 
 | 
						|
      =  (_Jv_IndirectCompiledClass*)klass->aux_info;
 | 
						|
 | 
						|
    for (int i = 0; i < klass->field_count; i++)
 | 
						|
      {
 | 
						|
	_Jv_Field *field = &klass->fields[i];
 | 
						|
 | 
						|
	if ((field->flags & java::lang::reflect::Modifier::STATIC) == 0)
 | 
						|
	  continue;
 | 
						|
 | 
						|
	char *base = field->isRef() ? reference_fields : non_reference_fields;
 | 
						|
	field->u.addr  = base + field->u.boffset;
 | 
						|
 | 
						|
	if (aux->field_initializers[i])
 | 
						|
	  {
 | 
						|
	    int field_size;
 | 
						|
	    if (! field->isRef ())
 | 
						|
	      field_size = field->type->size ();
 | 
						|
	    else 
 | 
						|
	      field_size = sizeof (jobject);
 | 
						|
 | 
						|
	    memcpy (field->u.addr, aux->field_initializers[i], field_size);
 | 
						|
	  }
 | 
						|
      } 
 | 
						|
    _Jv_Free (aux->field_initializers);
 | 
						|
  }
 | 
						|
 | 
						|
#ifdef INTERPRETER
 | 
						|
  static _Jv_ClosureList **do_get_closure_list (jclass klass)
 | 
						|
  {
 | 
						|
    _Jv_IndirectCompiledClass *aux = get_aux_info (klass);
 | 
						|
 | 
						|
    if (!aux->closures)
 | 
						|
      aux->closures = _Jv_ClosureListFinalizer ();
 | 
						|
 | 
						|
    return aux->closures;
 | 
						|
  }
 | 
						|
#endif
 | 
						|
};
 | 
						|
 | 
						|
#ifdef INTERPRETER
 | 
						|
 | 
						|
// This handles interpreted code.
 | 
						|
class _Jv_InterpreterEngine : public _Jv_ExecutionEngine
 | 
						|
{
 | 
						|
 public:
 | 
						|
 | 
						|
  static void do_verify (jclass);
 | 
						|
  static void do_allocate_static_fields (jclass, int, int);
 | 
						|
  static void do_create_ncode (jclass);
 | 
						|
  static _Jv_ResolvedMethod *do_resolve_method (_Jv_Method *, jclass,
 | 
						|
						jboolean);
 | 
						|
 | 
						|
  static bool do_need_resolve_string_fields ()
 | 
						|
  {
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  static void do_unregister(jclass klass)
 | 
						|
  {
 | 
						|
    _Jv_UnregisterClass(klass);
 | 
						|
  }
 | 
						|
 | 
						|
  static void do_allocate_field_initializers (jclass)
 | 
						|
  {
 | 
						|
  }
 | 
						|
 | 
						|
  static void do_post_miranda_hook (jclass);
 | 
						|
 | 
						|
  static _Jv_ClosureList **do_get_closure_list (jclass klass);
 | 
						|
 | 
						|
  _Jv_InterpreterEngine ()
 | 
						|
  {
 | 
						|
    unregister = do_unregister;
 | 
						|
    need_resolve_string_fields = do_need_resolve_string_fields;
 | 
						|
    verify = do_verify;
 | 
						|
    allocate_static_fields = do_allocate_static_fields;
 | 
						|
    allocate_field_initializers = do_allocate_field_initializers;
 | 
						|
    create_ncode = do_create_ncode;
 | 
						|
    resolve_method = do_resolve_method;
 | 
						|
    post_miranda_hook = do_post_miranda_hook;
 | 
						|
    get_closure_list = do_get_closure_list;
 | 
						|
  }
 | 
						|
 | 
						|
  // These operators make it so we don't have to link in libstdc++.
 | 
						|
  void *operator new (size_t bytes)
 | 
						|
  {
 | 
						|
    return _Jv_Malloc(bytes);
 | 
						|
  }
 | 
						|
 | 
						|
  void operator delete (void *mem)
 | 
						|
  {
 | 
						|
    _Jv_Free(mem);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
extern _Jv_InterpreterEngine _Jv_soleInterpreterEngine;
 | 
						|
#endif // INTERPRETER
 | 
						|
 | 
						|
extern _Jv_CompiledEngine _Jv_soleCompiledEngine;
 | 
						|
extern _Jv_IndirectCompiledEngine _Jv_soleIndirectCompiledEngine;
 | 
						|
#endif // __JAVA_EXECUTION_H__
 |