Ignore:
Timestamp:
Apr 27, 2004, 8:39:34 PM (21 years ago)
Author:
bird
Message:

GCC v3.3.3 sources.

Location:
branches/GNU/src/gcc
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/GNU/src/gcc

    • Property svn:ignore
      •  

        old new  
        2626configure.vr
        2727configure.vrs
         28dir.info
        2829Makefile
        29 dir.info
        3030lost+found
        3131update.out
  • branches/GNU/src/gcc/libjava/interpret.cc

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.1.1.2
    r1390 r1391  
    11// interpret.cc - Code for the interpreter
    22
    3 /* Copyright (C) 1999, 2000, 2001 , 2002 Free Software Foundation
     3/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation
    44
    55   This file is part of libgcj.
     
    1313#include <config.h>
    1414
     15// Define this to get the direct-threaded interpreter.  If undefined,
     16// we revert to a basic bytecode interpreter.  The former is faster
     17// but uses more memory.
     18#define DIRECT_THREADED
     19
    1520#pragma implementation "java-interp.h"
    1621
     
    1823#include <java-cpool.h>
    1924#include <java-interp.h>
    20 // #include <java/lang/fdlibm.h>
    2125#include <java/lang/System.h>
    2226#include <java/lang/String.h>
     
    3236#include <java/lang/ArithmeticException.h>
    3337#include <java/lang/IncompatibleClassChangeError.h>
     38#include <java/lang/Thread.h>
    3439#include <java-insns.h>
    3540#include <java-signal.h>
     
    5156
    5257extern "C" double __ieee754_fmod (double,double);
     58
     59// This represents a single slot in the "compiled" form of the
     60// bytecode.
     61union insn_slot
     62{
     63  // Address of code.
     64  void *insn;
     65  // An integer value used by an instruction.
     66  jint int_val;
     67  // A pointer value used by an instruction.
     68  void *datum;
     69};
     70
     71// The type of the PC depends on whether we're doing direct threading
     72// or a more ordinary bytecode interpreter.
     73#ifdef DIRECT_THREADED
     74typedef insn_slot *pc_t;
     75#else
     76typedef unsigned char *pc_t;
     77#endif
    5378
    5479static inline void dupx (_Jv_word *sp, int n, int x)
     
    200225#ifdef HANDLE_SEGV
    201226#define NULLCHECK(X)
    202 #define NULLARRAYCHECK(X) do { SAVE_PC; } while (0)
     227#define NULLARRAYCHECK(X)
    203228#else
    204229#define NULLCHECK(X) \
    205230  do { if ((X)==NULL) throw_null_pointer_exception (); } while (0)
    206231#define NULLARRAYCHECK(X) \
    207   do { if ((X)==NULL) { SAVE_PC; throw_null_pointer_exception (); } } while (0)
     232  do { if ((X)==NULL) { throw_null_pointer_exception (); } } while (0)
    208233#endif
    209234
     
    216241  while (0)
    217242
    218 // this method starts the actual running of the method.  It is inlined
    219 // in three different variants in the static methods run_normal,
    220 // run_sync_object and run_sync_class (see below).  Those static methods
    221 // are installed directly in the stub for this method (by
    222 // _Jv_InterpMethod::ncode, in resolve.cc).
    223 
    224 inline jobject
    225 _Jv_InterpMethod::run (ffi_cif* cif,
    226                        void *retp,
    227                        ffi_raw *args,
    228                        _Jv_InterpMethodInvocation *inv)
     243void _Jv_InterpMethod::run_normal (ffi_cif *,
     244                                   void* ret,
     245                                   ffi_raw * args,
     246                                   void* __this)
    229247{
    230   inv->running  = this;
    231   inv->pc       = bytecode ();
    232   inv->sp       = inv->stack_base ();
    233   _Jv_word *locals = inv->local_base ();
     248  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
     249  _this->run (ret, args);
     250}
     251
     252void _Jv_InterpMethod::run_synch_object (ffi_cif *,
     253                                         void* ret,
     254                                         ffi_raw * args,
     255                                         void* __this)
     256{
     257  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
     258
     259  jobject rcv = (jobject) args[0].ptr;
     260  JvSynchronize mutex (rcv);
     261
     262  _this->run (ret, args);
     263}
     264
     265void _Jv_InterpMethod::run_synch_class (ffi_cif *,
     266                                        void* ret,
     267                                        ffi_raw * args,
     268                                        void* __this)
     269{
     270  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
     271
     272  jclass sync = _this->defining_class;
     273  JvSynchronize mutex (sync);
     274
     275  _this->run (ret, args);
     276}
     277
     278#ifdef DIRECT_THREADED
     279// "Compile" a method by turning it from bytecode to direct-threaded
     280// code.
     281void
     282_Jv_InterpMethod::compile (const void * const *insn_targets)
     283{
     284  insn_slot *insns = NULL;
     285  int next = 0;
     286  unsigned char *codestart = bytecode ();
     287  unsigned char *end = codestart + code_length;
     288  _Jv_word *pool_data = defining_class->constants.data;
     289
     290#define SET_ONE(Field, Value)                                                 \
     291  do                                                                          \
     292    {                                                                         \
     293      if (first_pass)                                                         \
     294        ++next;                                                               \
     295      else                                                                    \
     296        insns[next++].Field = Value;                                          \
     297    }                                                                         \
     298  while (0)
     299
     300#define SET_INSN(Value) SET_ONE (insn, (void *) Value)
     301#define SET_INT(Value) SET_ONE (int_val, Value)
     302#define SET_DATUM(Value) SET_ONE (datum, Value)
     303
     304  // Map from bytecode PC to slot in INSNS.
     305  int *pc_mapping = (int *) __builtin_alloca (sizeof (int) * code_length);
     306  for (int i = 0; i < code_length; ++i)
     307    pc_mapping[i] = -1;
     308
     309  for (int i = 0; i < 2; ++i)
     310    {
     311      jboolean first_pass = i == 0;
     312
     313      if (! first_pass)
     314        {
     315          insns = (insn_slot *) _Jv_AllocBytes (sizeof (insn_slot) * next);
     316          next = 0;
     317        }
     318
     319      unsigned char *pc = codestart;
     320      while (pc < end)
     321        {
     322          int base_pc_val = pc - codestart;
     323          if (first_pass)
     324            pc_mapping[base_pc_val] = next;
     325
     326          java_opcode opcode = (java_opcode) *pc++;
     327          // Just elide NOPs.
     328          if (opcode == op_nop)
     329            continue;
     330          SET_INSN (insn_targets[opcode]);
     331
     332          switch (opcode)
     333            {
     334            case op_nop:
     335            case op_aconst_null:
     336            case op_iconst_m1:
     337            case op_iconst_0:
     338            case op_iconst_1:
     339            case op_iconst_2:
     340            case op_iconst_3:
     341            case op_iconst_4:
     342            case op_iconst_5:
     343            case op_lconst_0:
     344            case op_lconst_1:
     345            case op_fconst_0:
     346            case op_fconst_1:
     347            case op_fconst_2:
     348            case op_dconst_0:
     349            case op_dconst_1:
     350            case op_iload_0:
     351            case op_iload_1:
     352            case op_iload_2:
     353            case op_iload_3:
     354            case op_lload_0:
     355            case op_lload_1:
     356            case op_lload_2:
     357            case op_lload_3:
     358            case op_fload_0:
     359            case op_fload_1:
     360            case op_fload_2:
     361            case op_fload_3:
     362            case op_dload_0:
     363            case op_dload_1:
     364            case op_dload_2:
     365            case op_dload_3:
     366            case op_aload_0:
     367            case op_aload_1:
     368            case op_aload_2:
     369            case op_aload_3:
     370            case op_iaload:
     371            case op_laload:
     372            case op_faload:
     373            case op_daload:
     374            case op_aaload:
     375            case op_baload:
     376            case op_caload:
     377            case op_saload:
     378            case op_istore_0:
     379            case op_istore_1:
     380            case op_istore_2:
     381            case op_istore_3:
     382            case op_lstore_0:
     383            case op_lstore_1:
     384            case op_lstore_2:
     385            case op_lstore_3:
     386            case op_fstore_0:
     387            case op_fstore_1:
     388            case op_fstore_2:
     389            case op_fstore_3:
     390            case op_dstore_0:
     391            case op_dstore_1:
     392            case op_dstore_2:
     393            case op_dstore_3:
     394            case op_astore_0:
     395            case op_astore_1:
     396            case op_astore_2:
     397            case op_astore_3:
     398            case op_iastore:
     399            case op_lastore:
     400            case op_fastore:
     401            case op_dastore:
     402            case op_aastore:
     403            case op_bastore:
     404            case op_castore:
     405            case op_sastore:
     406            case op_pop:
     407            case op_pop2:
     408            case op_dup:
     409            case op_dup_x1:
     410            case op_dup_x2:
     411            case op_dup2:
     412            case op_dup2_x1:
     413            case op_dup2_x2:
     414            case op_swap:
     415            case op_iadd:
     416            case op_isub:
     417            case op_imul:
     418            case op_idiv:
     419            case op_irem:
     420            case op_ishl:
     421            case op_ishr:
     422            case op_iushr:
     423            case op_iand:
     424            case op_ior:
     425            case op_ixor:
     426            case op_ladd:
     427            case op_lsub:
     428            case op_lmul:
     429            case op_ldiv:
     430            case op_lrem:
     431            case op_lshl:
     432            case op_lshr:
     433            case op_lushr:
     434            case op_land:
     435            case op_lor:
     436            case op_lxor:
     437            case op_fadd:
     438            case op_fsub:
     439            case op_fmul:
     440            case op_fdiv:
     441            case op_frem:
     442            case op_dadd:
     443            case op_dsub:
     444            case op_dmul:
     445            case op_ddiv:
     446            case op_drem:
     447            case op_ineg:
     448            case op_i2b:
     449            case op_i2c:
     450            case op_i2s:
     451            case op_lneg:
     452            case op_fneg:
     453            case op_dneg:
     454            case op_i2l:
     455            case op_i2f:
     456            case op_i2d:
     457            case op_l2i:
     458            case op_l2f:
     459            case op_l2d:
     460            case op_f2i:
     461            case op_f2l:
     462            case op_f2d:
     463            case op_d2i:
     464            case op_d2l:
     465            case op_d2f:
     466            case op_lcmp:
     467            case op_fcmpl:
     468            case op_fcmpg:
     469            case op_dcmpl:
     470            case op_dcmpg:
     471            case op_monitorenter:
     472            case op_monitorexit:
     473            case op_ireturn:
     474            case op_lreturn:
     475            case op_freturn:
     476            case op_dreturn:
     477            case op_areturn:
     478            case op_return:
     479            case op_athrow:
     480            case op_arraylength:
     481              // No argument, nothing else to do.
     482              break;
     483
     484            case op_bipush:
     485              SET_INT (get1s (pc));
     486              ++pc;
     487              break;
     488
     489            case op_ldc:
     490              {
     491                int index = get1u (pc);
     492                ++pc;
     493                SET_DATUM (pool_data[index].o);
     494              }
     495              break;
     496
     497            case op_ret:
     498            case op_iload:
     499            case op_lload:
     500            case op_fload:
     501            case op_dload:
     502            case op_aload:
     503            case op_istore:
     504            case op_lstore:
     505            case op_fstore:
     506            case op_dstore:
     507            case op_astore:
     508            case op_newarray:
     509              SET_INT (get1u (pc));
     510              ++pc;
     511              break;
     512
     513            case op_iinc:
     514              SET_INT (get1u (pc));
     515              SET_INT (get1s (pc + 1));
     516              pc += 2;
     517              break;
     518
     519            case op_ldc_w:
     520              {
     521                int index = get2u (pc);
     522                pc += 2;
     523                SET_DATUM (pool_data[index].o);
     524              }
     525              break;
     526
     527            case op_ldc2_w:
     528              {
     529                int index = get2u (pc);
     530                pc += 2;
     531                SET_DATUM (&pool_data[index]);
     532              }
     533              break;
     534
     535            case op_sipush:
     536              SET_INT (get2s (pc));
     537              pc += 2;
     538              break;
     539
     540            case op_new:
     541            case op_getstatic:
     542            case op_getfield:
     543            case op_putfield:
     544            case op_putstatic:
     545            case op_anewarray:
     546            case op_instanceof:
     547            case op_checkcast:
     548            case op_invokespecial:
     549            case op_invokestatic:
     550            case op_invokevirtual:
     551              SET_INT (get2u (pc));
     552              pc += 2;
     553              break;
     554
     555            case op_multianewarray:
     556              SET_INT (get2u (pc));
     557              SET_INT (get1u (pc + 2));
     558              pc += 3;
     559              break;
     560
     561            case op_jsr:
     562            case op_ifeq:
     563            case op_ifne:
     564            case op_iflt:
     565            case op_ifge:
     566            case op_ifgt:
     567            case op_ifle:
     568            case op_if_icmpeq:
     569            case op_if_icmpne:
     570            case op_if_icmplt:
     571            case op_if_icmpge:
     572            case op_if_icmpgt:
     573            case op_if_icmple:
     574            case op_if_acmpeq:
     575            case op_if_acmpne:
     576            case op_ifnull:
     577            case op_ifnonnull:
     578            case op_goto:
     579              {
     580                int offset = get2s (pc);
     581                pc += 2;
     582
     583                int new_pc = base_pc_val + offset;
     584
     585                bool orig_was_goto = opcode == op_goto;
     586
     587                // Thread jumps.  We limit the loop count; this lets
     588                // us avoid infinite loops if the bytecode contains
     589                // such.  `10' is arbitrary.
     590                int count = 10;
     591                while (codestart[new_pc] == op_goto && count-- > 0)
     592                  new_pc += get2s (&codestart[new_pc + 1]);
     593
     594                // If the jump takes us to a `return' instruction and
     595                // the original branch was an unconditional goto, then
     596                // we hoist the return.
     597                opcode = (java_opcode) codestart[new_pc];
     598                if (orig_was_goto
     599                    && (opcode == op_ireturn || opcode == op_lreturn
     600                        || opcode == op_freturn || opcode == op_dreturn
     601                        || opcode == op_areturn || opcode == op_return))
     602                  {
     603                    --next;
     604                    SET_INSN (insn_targets[opcode]);
     605                  }
     606                else
     607                  SET_DATUM (&insns[pc_mapping[new_pc]]);
     608              }
     609              break;
     610
     611            case op_tableswitch:
     612              {
     613                while ((pc - codestart) % 4 != 0)
     614                  ++pc;
     615
     616                jint def = get4 (pc);
     617                SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
     618                pc += 4;
     619
     620                int low = get4 (pc);
     621                SET_INT (low);
     622                pc += 4;
     623                int high = get4 (pc);
     624                SET_INT (high);
     625                pc += 4;
     626
     627                for (int i = low; i <= high; ++i)
     628                  {
     629                    SET_DATUM (&insns[pc_mapping[base_pc_val + get4 (pc)]]);
     630                    pc += 4;
     631                  }
     632              }
     633              break;
     634
     635            case op_lookupswitch:
     636              {
     637                while ((pc - codestart) % 4 != 0)
     638                  ++pc;
     639
     640                jint def = get4 (pc);
     641                SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
     642                pc += 4;
     643
     644                jint npairs = get4 (pc);
     645                pc += 4;
     646                SET_INT (npairs);
     647
     648                while (npairs-- > 0)
     649                  {
     650                    jint match = get4 (pc);
     651                    jint offset = get4 (pc + 4);
     652                    SET_INT (match);
     653                    SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
     654                    pc += 8;
     655                  }
     656              }
     657              break;
     658
     659            case op_invokeinterface:
     660              {
     661                jint index = get2u (pc);
     662                pc += 2;
     663                // We ignore the next two bytes.
     664                pc += 2;
     665                SET_INT (index);
     666              }
     667              break;
     668
     669            case op_wide:
     670              {
     671                opcode = (java_opcode) get1u (pc);
     672                pc += 1;
     673                jint val = get2u (pc);
     674                pc += 2;
     675
     676                // We implement narrow and wide instructions using the
     677                // same code in the interpreter.  So we rewrite the
     678                // instruction slot here.
     679                if (! first_pass)
     680                  insns[next - 1].insn = (void *) insn_targets[opcode];
     681                SET_INT (val);
     682
     683                if (opcode == op_iinc)
     684                  {
     685                    SET_INT (get2s (pc));
     686                    pc += 2;
     687                  }
     688              }
     689              break;
     690
     691            case op_jsr_w:
     692            case op_goto_w:
     693              {
     694                jint offset = get4 (pc);
     695                pc += 4;
     696                SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
     697              }
     698              break;
     699
     700            // Some "can't happen" cases that we include for
     701            // error-checking purposes.
     702            case op_putfield_1:
     703            case op_putfield_2:
     704            case op_putfield_4:
     705            case op_putfield_8:
     706            case op_putfield_a:
     707            case op_putstatic_1:
     708            case op_putstatic_2:
     709            case op_putstatic_4:
     710            case op_putstatic_8:
     711            case op_putstatic_a:
     712            case op_getfield_1:
     713            case op_getfield_2s:
     714            case op_getfield_2u:
     715            case op_getfield_4:
     716            case op_getfield_8:
     717            case op_getfield_a:
     718            case op_getstatic_1:
     719            case op_getstatic_2s:
     720            case op_getstatic_2u:
     721            case op_getstatic_4:
     722            case op_getstatic_8:
     723            case op_getstatic_a:
     724            default:
     725              // Fail somehow.
     726              break;
     727            }
     728        }
     729    }
     730
     731  // Now update exceptions.
     732  _Jv_InterpException *exc = exceptions ();
     733  for (int i = 0; i < exc_count; ++i)
     734    {
     735      exc[i].start_pc.p = &insns[pc_mapping[exc[i].start_pc.i]];
     736      exc[i].end_pc.p = &insns[pc_mapping[exc[i].end_pc.i]];
     737      exc[i].handler_pc.p = &insns[pc_mapping[exc[i].handler_pc.i]];
     738      jclass handler = (_Jv_ResolvePoolEntry (defining_class,
     739                                              exc[i].handler_type.i)).clazz;
     740      exc[i].handler_type.p = handler;
     741    }
     742
     743  prepared = insns;
     744}
     745#endif /* DIRECT_THREADED */
     746
     747// This function exists so that the stack-tracing code can find the
     748// boundaries of the interpreter.
     749void
     750_Jv_StartOfInterpreter (void)
     751{
     752}
     753
     754void
     755_Jv_InterpMethod::run (void *retp, ffi_raw *args)
     756{
     757  using namespace java::lang::reflect;
     758
     759  // FRAME_DESC registers this particular invocation as the top-most
     760  // interpreter frame.  This lets the stack tracing code (for
     761  // Throwable) print information about the method being interpreted
     762  // rather than about the interpreter itself.  FRAME_DESC has a
     763  // destructor so it cleans up automatically when the interpreter
     764  // returns.
     765  java::lang::Thread *thread = java::lang::Thread::currentThread();
     766  _Jv_MethodChain frame_desc (this,
     767                              (_Jv_MethodChain **) &thread->interp_frame);
     768
     769  _Jv_word stack[max_stack];
     770  _Jv_word *sp = stack;
     771
     772  _Jv_word locals[max_locals];
    234773
    235774  /* Go straight at it!  the ffi raw format matches the internal
     
    238777  memcpy ((void*) locals, (void*) args, args_raw_size);
    239778
    240  next_segment:
    241 
    242   jobject ex = NULL;
    243 
    244   try
    245     {
    246       continue1 (inv);
    247     }
    248   catch (java::lang::Throwable *ex2)
    249     {
    250       ex = ex2;
    251     }
    252 
    253   if (ex == 0)                  // no exception...
    254     {
    255       /* define sp locally, so the POP? macros will pick it up */
    256       _Jv_word *sp = inv->sp;
    257       int rtype = cif->rtype->type;
    258 
    259       if (rtype == FFI_TYPE_POINTER)
    260         {
    261           jobject r = POPA();
    262           *(jobject*) retp = r;
    263           return 0;
    264         }
    265       else if (rtype == FFI_TYPE_SINT32)
    266         {
    267           jint r = POPI();
    268           *(jint*)retp = r;
    269           return 0;
    270         }
    271       else if (rtype == FFI_TYPE_VOID)
    272         {
    273           return 0;
    274         }
    275       else switch (rtype)
    276         {
    277         case FFI_TYPE_FLOAT:
    278           {
    279             jfloat r = POPF();
    280             *(jfloat*)retp = r;
    281             return 0;
    282           }
    283      
    284         case FFI_TYPE_DOUBLE:
    285           {
    286             jdouble r = POPD();
    287             *(jdouble*)retp = r;
    288             return 0;
    289           }
    290 
    291         case FFI_TYPE_UINT8:
    292         case FFI_TYPE_UINT16:
    293         case FFI_TYPE_UINT32:
    294         case FFI_TYPE_SINT8:
    295         case FFI_TYPE_SINT16:
    296           {
    297             jint r = POPI();
    298             *(jint*)retp = r;
    299             return 0;
    300           }
    301      
    302         case FFI_TYPE_SINT64:
    303           {
    304             jlong r = POPL();
    305             *(jlong*)retp = r;
    306             return 0;
    307           }
    308        
    309         default:
    310           throw_internal_error ("unknown return type");
    311         }
    312     }
    313 
    314   /** handle an exception */
    315   if ( find_exception (ex, inv) )
    316     goto next_segment;
    317 
    318   return ex;
    319 }
    320 
    321 #define SAVE_PC   inv->pc = pc
    322 
    323 bool _Jv_InterpMethod::find_exception (jobject ex,
    324                                        _Jv_InterpMethodInvocation *inv)
    325 {
    326   // We subtract one because the PC was incremented before it was
    327   // saved.
    328   int logical_pc = inv->pc - 1 - bytecode ();
    329   _Jv_InterpException *exc = exceptions ();
    330   jclass exc_class = ex->getClass ();
    331 
    332   for (int i = 0; i < exc_count; i++)
    333     {
    334       if (exc[i].start_pc <= logical_pc && logical_pc < exc[i].end_pc)
    335         {       
    336           jclass handler;
    337 
    338           if (exc[i].handler_type != 0)
    339             handler = (_Jv_ResolvePoolEntry (defining_class,
    340                                              exc[i].handler_type)).clazz;
    341           else
    342             handler = NULL;
    343          
    344           if (handler==NULL || handler->isAssignableFrom (exc_class))
    345             {
    346               inv->pc = bytecode () + exc[i].handler_pc;
    347               inv->sp = inv->stack_base (); // reset stack
    348               (inv->sp++)->o = ex; // push exception
    349               return true;
    350             }
    351         }
    352     }
    353   return false;
    354 }
    355 
    356 void _Jv_InterpMethod::run_normal (ffi_cif* cif,
    357                                    void* ret,
    358                                    ffi_raw * args,
    359                                    void* __this)
    360 {
    361   _Jv_InterpMethod* _this = (_Jv_InterpMethod*)__this;
    362 
    363   // we do the alloca of the method invocation here, to allow the method
    364   // "run" ro be inlined.  Otherwise gcc will ignore the inline directive.
    365   int storage_size = _this->max_stack+_this->max_locals;
    366   _Jv_InterpMethodInvocation* inv = (_Jv_InterpMethodInvocation*)
    367     __builtin_alloca (sizeof (_Jv_InterpMethodInvocation)
    368                       + storage_size * sizeof (_Jv_word));
    369 
    370   jobject ex = _this->run (cif, ret, args, inv);
    371   if (ex != 0) throw static_cast<jthrowable>(ex);
    372 }
    373 
    374 void _Jv_InterpMethod::run_synch_object (ffi_cif* cif,
    375                                          void* ret,
    376                                          ffi_raw * args,
    377                                          void* __this)
    378 {
    379   _Jv_InterpMethod* _this = (_Jv_InterpMethod*)__this;
    380   jobject rcv = (jobject)args[0].ptr;
    381 
    382   int storage_size = _this->max_stack+_this->max_locals;
    383   _Jv_InterpMethodInvocation* inv = (_Jv_InterpMethodInvocation*)
    384     __builtin_alloca (sizeof (_Jv_InterpMethodInvocation)
    385                       + storage_size * sizeof (_Jv_word));
    386 
    387   _Jv_MonitorEnter (rcv);
    388   jobject ex = _this->run (cif, ret, args, inv);
    389   _Jv_MonitorExit (rcv);
    390 
    391   if (ex != 0) throw static_cast<jthrowable>(ex);
    392 }
    393 
    394 void _Jv_InterpMethod::run_synch_class (ffi_cif* cif,
    395                                         void* ret,
    396                                         ffi_raw * args,
    397                                         void* __this)
    398 {
    399   _Jv_InterpMethod* _this = (_Jv_InterpMethod*)__this;
    400   jclass  sync = _this->defining_class;
    401 
    402   int storage_size = _this->max_stack+_this->max_locals;
    403   _Jv_InterpMethodInvocation* inv = (_Jv_InterpMethodInvocation*)
    404     __builtin_alloca (sizeof (_Jv_InterpMethodInvocation)
    405                       + storage_size * sizeof (_Jv_word));
    406 
    407   _Jv_MonitorEnter (sync);
    408   jobject ex = _this->run (cif, ret, args, inv);
    409   _Jv_MonitorExit (sync);
    410 
    411   if (ex != 0) throw static_cast<jthrowable>(ex);
    412 }
    413 
    414 /*
    415   This proceeds execution, as designated in "inv".  If an exception
    416   happens, then it is simply thrown, and handled in Java.  Thus, the pc
    417   needs to be stored in the inv->pc at all times, so we can figure
    418   out which handler (if any) to invoke.
    419 
    420   One design issue, which I have not completely considered, is if it
    421   should be possible to have interpreted classes linked in!  Seldom used
    422   (or non-critical) classes could reasonably be interpreted. 
    423 */
    424 
    425 
    426 void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation *inv)
    427 {
    428   using namespace java::lang::reflect;
    429 
    430   _Jv_word      *sp     = inv->sp;
    431   unsigned char *pc     = inv->pc;
    432   _Jv_word               *locals = inv->local_base ();
    433 
    434   _Jv_word *pool_data   = defining_class->constants.data;
    435  
    436   /* these two are used in the invokeXXX instructions */
     779  _Jv_word *pool_data = defining_class->constants.data;
     780
     781  /* These three are temporaries for common code used by several
     782     instructions.  */
    437783  void (*fun)();
    438784  _Jv_ResolvedMethod* rmeth;
     785  int tmpval;
    439786
    440787#define INSN_LABEL(op) &&insn_##op
    441 #define GOTO_INSN(op) goto *(insn_target[op])
    442788
    443789  static const void *const insn_target[] =
     
    629975    INSN_LABEL(invokestatic),
    630976    INSN_LABEL(invokeinterface),
    631     0, /* op_xxxunusedxxx1, */
     977    0, /* Unused. */
    632978    INSN_LABEL(new),
    633979    INSN_LABEL(newarray),
     
    639985    INSN_LABEL(monitorenter),
    640986    INSN_LABEL(monitorexit),
     987#ifdef DIRECT_THREADED
     988    0, // wide
     989#else
    641990    INSN_LABEL(wide),
     991#endif
    642992    INSN_LABEL(multianewarray),
    643993    INSN_LABEL(ifnull),
     
    645995    INSN_LABEL(goto_w),
    646996    INSN_LABEL(jsr_w),
     997    0
    647998  };
    648999
    649   /* If the macro INLINE_SWITCH is not defined, then the main loop
    650      operates as one big (normal) switch statement.  If it is defined,
    651      then the case selection is performed `inline' in the end of the
    652      code for each case.  The latter saves a native branch instruction
    653      for each java-instruction, but expands the code size somewhat.
    654 
    655      NOTE: On i386 defining INLINE_SWITCH improves over all
    656      performance approximately seven percent, but it may be different
    657      for other machines.  At some point, this may be made into a proper
    658      configuration parameter.  */
    659 
    660 #define INLINE_SWITCH
    661 
    662 #ifdef  INLINE_SWITCH
    663 
    664 #define NEXT_INSN do { GOTO_INSN(*pc++); } while (0)
    665 
    666 
    667   NEXT_INSN;
     1000  pc_t pc;
     1001
     1002#ifdef DIRECT_THREADED
     1003
     1004#define NEXT_INSN goto *((pc++)->insn)
     1005#define INTVAL() ((pc++)->int_val)
     1006#define AVAL() ((pc++)->datum)
     1007
     1008#define GET1S() INTVAL ()
     1009#define GET2S() INTVAL ()
     1010#define GET1U() INTVAL ()
     1011#define GET2U() INTVAL ()
     1012#define AVAL1U() AVAL ()
     1013#define AVAL2U() AVAL ()
     1014#define AVAL2UP() AVAL ()
     1015#define SKIP_GOTO ++pc
     1016#define GOTO_VAL() (insn_slot *) pc->datum
     1017#define PCVAL(unionval) unionval.p
     1018#define AMPAMP(label) &&label
     1019
     1020  // Compile if we must.
     1021  if (prepared == NULL)
     1022    compile (insn_target);
     1023  pc = (insn_slot *) prepared;
     1024
    6681025#else
    6691026
    670 #define NEXT_INSN goto next_insn
    671 
    672  next_insn:
    673   GOTO_INSN (*pc++);
    674 
    675 #endif
    676 
    677   /* The first few instructions here are ordered according to their
    678      frequency, in the hope that this will improve code locality a
    679      little.  */
    680 
    681      insn_aload_0:              // 0x2a
    682       LOADA(0);
    683       NEXT_INSN;
    684 
    685      insn_iload:                // 0x15
    686       LOADI (get1u (pc++));
    687       NEXT_INSN;
    688 
    689      insn_iload_1:              // 0x1b
     1027#define NEXT_INSN goto *(insn_target[*pc++])
     1028
     1029#define GET1S() get1s (pc++)
     1030#define GET2S() (pc += 2, get2s (pc- 2))
     1031#define GET1U() get1u (pc++)
     1032#define GET2U() (pc += 2, get2u (pc - 2))
     1033#define AVAL1U() ({ int index = get1u (pc++); pool_data[index].o; })
     1034#define AVAL2U() ({ int index = get2u (pc); pc += 2; pool_data[index].o; })
     1035#define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
     1036#define SKIP_GOTO pc += 2
     1037#define GOTO_VAL() pc - 1 + get2s (pc)
     1038#define PCVAL(unionval) unionval.i
     1039#define AMPAMP(label) NULL
     1040
     1041  pc = bytecode ();
     1042
     1043#endif /* DIRECT_THREADED */
     1044
     1045#define TAKE_GOTO pc = GOTO_VAL ()
     1046
     1047  try
     1048    {
     1049      // We keep nop around.  It is used if we're interpreting the
     1050      // bytecodes and not doing direct threading.
     1051    insn_nop:
     1052      NEXT_INSN;
     1053
     1054      /* The first few instructions here are ordered according to their
     1055         frequency, in the hope that this will improve code locality a
     1056         little.  */
     1057
     1058    insn_aload_0:               // 0x2a
     1059      LOADA (0);
     1060      NEXT_INSN;
     1061
     1062    insn_iload:         // 0x15
     1063      LOADI (GET1U ());
     1064      NEXT_INSN;
     1065
     1066    insn_iload_1:               // 0x1b
    6901067      LOADI (1);
    6911068      NEXT_INSN;
    6921069
    693      insn_invokevirtual:        // 0xb6
    694       SAVE_PC;
    695       {
    696         int index = get2u (pc); pc += 2;
     1070    insn_invokevirtual: // 0xb6
     1071      {
     1072        int index = GET2U ();
    6971073
    6981074        /* _Jv_ResolvePoolEntry returns immediately if the value already
     
    7201096          {
    7211097            jobject rcv = sp[0].o;
    722             _Jv_VTable *table = *(_Jv_VTable**)rcv;
    723             fun = (void (*)()) table->get_method(rmeth->vtable_index);
     1098            _Jv_VTable *table = *(_Jv_VTable**) rcv;
     1099            fun = (void (*)()) table->get_method (rmeth->vtable_index);
    7241100          }
     1101
     1102#ifdef DIRECT_THREADED
     1103        // Rewrite instruction so that we use a faster pre-resolved
     1104        // method.
     1105        pc[-2].insn = &&invokevirtual_resolved;
     1106        pc[-1].datum = rmeth;
     1107#endif /* DIRECT_THREADED */
    7251108      }
    7261109      goto perform_invoke;
    7271110
    728      perform_invoke:
     1111#ifdef DIRECT_THREADED
     1112    invokevirtual_resolved:
     1113      {
     1114        rmeth = (_Jv_ResolvedMethod *) AVAL ();
     1115        sp -= rmeth->stack_item_count;
     1116        // We don't use NULLCHECK here because we can't rely on that
     1117        // working if the method is final.  So instead we do an
     1118        // explicit test.
     1119        if (! sp[0].o)
     1120          throw new java::lang::NullPointerException;
     1121
     1122        if (rmeth->vtable_index == -1)
     1123          {
     1124            // final methods do not appear in the vtable,
     1125            // if it does not appear in the superclass.
     1126            fun = (void (*)()) rmeth->method->ncode;
     1127          }
     1128        else
     1129          {
     1130            jobject rcv = sp[0].o;
     1131            _Jv_VTable *table = *(_Jv_VTable**) rcv;
     1132            fun = (void (*)()) table->get_method (rmeth->vtable_index);
     1133          }
     1134      }
     1135      goto perform_invoke;
     1136#endif /* DIRECT_THREADED */
     1137
     1138    perform_invoke:
    7291139      {
    7301140        /* here goes the magic again... */
     
    7581168            /* skip */
    7591169          }
    760         else switch (rtype)
     1170        else
    7611171          {
    762           case FFI_TYPE_SINT8:
    763             {
    764               jbyte value = (*(jint*)&rvalue) & 0xff;
    765               PUSHI (value);
    766             }
    767             break;
    768 
    769           case FFI_TYPE_SINT16:
    770             {
    771               jshort value = (*(jint*)&rvalue) & 0xffff;
    772               PUSHI (value);
    773             }
    774             break;
    775 
    776           case FFI_TYPE_UINT16:
    777             {
    778               jint value = (*(jint*)&rvalue) & 0xffff;
    779               PUSHI (value);
    780             }
    781             break;
    782 
    783           case FFI_TYPE_FLOAT:
    784             PUSHF (*(jfloat*)&rvalue);
    785             break;
    786 
    787           case FFI_TYPE_DOUBLE:
    788             PUSHD (rvalue);
    789             break;
    790 
    791           case FFI_TYPE_SINT64:
    792             PUSHL (*(jlong*)&rvalue);
    793             break;
    794 
    795           default:
    796             throw_internal_error ("unknown return type in invokeXXX");
     1172            switch (rtype)
     1173              {
     1174              case FFI_TYPE_SINT8:
     1175                {
     1176                  jbyte value = (*(jint*)&rvalue) & 0xff;
     1177                  PUSHI (value);
     1178                }
     1179                break;
     1180
     1181              case FFI_TYPE_SINT16:
     1182                {
     1183                  jshort value = (*(jint*)&rvalue) & 0xffff;
     1184                  PUSHI (value);
     1185                }
     1186                break;
     1187
     1188              case FFI_TYPE_UINT16:
     1189                {
     1190                  jint value = (*(jint*)&rvalue) & 0xffff;
     1191                  PUSHI (value);
     1192                }
     1193                break;
     1194
     1195              case FFI_TYPE_FLOAT:
     1196                PUSHF (*(jfloat*)&rvalue);
     1197                break;
     1198
     1199              case FFI_TYPE_DOUBLE:
     1200                PUSHD (rvalue);
     1201                break;
     1202
     1203              case FFI_TYPE_SINT64:
     1204                PUSHL (*(jlong*)&rvalue);
     1205                break;
     1206
     1207              default:
     1208                throw_internal_error ("unknown return type in invokeXXX");
     1209              }
    7971210          }
    798 
    799       }
    800       NEXT_INSN;
    801 
    802 
    803      insn_nop:
    804       NEXT_INSN;
    805 
    806      insn_aconst_null:
     1211      }
     1212      NEXT_INSN;
     1213
     1214    insn_aconst_null:
    8071215      PUSHA (NULL);
    8081216      NEXT_INSN;
    8091217
    810      insn_iconst_m1:
     1218    insn_iconst_m1:
    8111219      PUSHI (-1);
    8121220      NEXT_INSN;
    8131221
    814      insn_iconst_0:
     1222    insn_iconst_0:
    8151223      PUSHI (0);
    8161224      NEXT_INSN;
    8171225
    818      insn_iconst_1:
     1226    insn_iconst_1:
    8191227      PUSHI (1);
    8201228      NEXT_INSN;
    8211229
    822      insn_iconst_2:
     1230    insn_iconst_2:
    8231231      PUSHI (2);
    8241232      NEXT_INSN;
    8251233
    826      insn_iconst_3:
     1234    insn_iconst_3:
    8271235      PUSHI (3);
    8281236      NEXT_INSN;
    8291237
    830      insn_iconst_4:
     1238    insn_iconst_4:
    8311239      PUSHI (4);
    8321240      NEXT_INSN;
    8331241
    834      insn_iconst_5:
     1242    insn_iconst_5:
    8351243      PUSHI (5);
    8361244      NEXT_INSN;
    8371245
    838      insn_lconst_0:
     1246    insn_lconst_0:
    8391247      PUSHL (0);
    8401248      NEXT_INSN;
    8411249
    842      insn_lconst_1:
     1250    insn_lconst_1:
    8431251      PUSHL (1);
    8441252      NEXT_INSN;
    8451253
    846      insn_fconst_0:
     1254    insn_fconst_0:
    8471255      PUSHF (0);
    8481256      NEXT_INSN;
    8491257
    850      insn_fconst_1:
     1258    insn_fconst_1:
    8511259      PUSHF (1);
    8521260      NEXT_INSN;
    8531261
    854      insn_fconst_2:
     1262    insn_fconst_2:
    8551263      PUSHF (2);
    8561264      NEXT_INSN;
    8571265
    858      insn_dconst_0:
     1266    insn_dconst_0:
    8591267      PUSHD (0);
    8601268      NEXT_INSN;
    8611269
    862      insn_dconst_1:
     1270    insn_dconst_1:
    8631271      PUSHD (1);
    8641272      NEXT_INSN;
    8651273
    866      insn_bipush:
    867       PUSHI (get1s(pc++));
    868       NEXT_INSN;
    869 
    870      insn_sipush:
    871       PUSHI (get2s(pc)); pc += 2;
    872       NEXT_INSN;
    873 
    874      insn_ldc:
    875       {
    876         int index = get1u (pc++);
    877         PUSHA(pool_data[index].o);
    878       }
    879       NEXT_INSN;
    880 
    881      insn_ldc_w:
    882       {
    883         int index = get2u (pc); pc += 2;
    884         PUSHA(pool_data[index].o);
    885       }
    886       NEXT_INSN;
    887 
    888      insn_ldc2_w:
    889       {
    890         int index = get2u (pc); pc += 2;
    891         memcpy (sp, &pool_data[index], 2*sizeof (_Jv_word));
     1274    insn_bipush:
     1275      // For direct threaded, bipush and sipush are the same.
     1276#ifndef DIRECT_THREADED
     1277      PUSHI (GET1S ());
     1278      NEXT_INSN;
     1279#endif /* DIRECT_THREADED */
     1280    insn_sipush:
     1281      PUSHI (GET2S ());
     1282      NEXT_INSN;
     1283
     1284    insn_ldc:
     1285      // For direct threaded, ldc and ldc_w are the same.
     1286#ifndef DIRECT_THREADED
     1287      PUSHA ((jobject) AVAL1U ());
     1288      NEXT_INSN;
     1289#endif /* DIRECT_THREADED */
     1290    insn_ldc_w:
     1291      PUSHA ((jobject) AVAL2U ());
     1292      NEXT_INSN;
     1293
     1294    insn_ldc2_w:
     1295      {
     1296        void *where = AVAL2UP ();
     1297        memcpy (sp, where, 2*sizeof (_Jv_word));
    8921298        sp += 2;
    8931299      }
    8941300      NEXT_INSN;
    8951301
    896      insn_lload:
    897       LOADL (get1u (pc++));
    898       NEXT_INSN;
    899 
    900      insn_fload:
    901       LOADF (get1u (pc++));
    902       NEXT_INSN;
    903 
    904      insn_dload:
    905       LOADD (get1u (pc++));
    906       NEXT_INSN;
    907 
    908      insn_aload:
    909       LOADA (get1u (pc++));
    910       NEXT_INSN;
    911 
    912      insn_iload_0:
     1302    insn_lload:
     1303      LOADL (GET1U ());
     1304      NEXT_INSN;
     1305
     1306    insn_fload:
     1307      LOADF (GET1U ());
     1308      NEXT_INSN;
     1309
     1310    insn_dload:
     1311      LOADD (GET1U ());
     1312      NEXT_INSN;
     1313
     1314    insn_aload:
     1315      LOADA (GET1U ());
     1316      NEXT_INSN;
     1317
     1318    insn_iload_0:
    9131319      LOADI (0);
    9141320      NEXT_INSN;
    9151321
    916      insn_iload_2:
     1322    insn_iload_2:
    9171323      LOADI (2);
    9181324      NEXT_INSN;
    9191325
    920      insn_iload_3:
     1326    insn_iload_3:
    9211327      LOADI (3);
    9221328      NEXT_INSN;
    9231329
    924      insn_lload_0:
     1330    insn_lload_0:
    9251331      LOADL (0);
    9261332      NEXT_INSN;
    9271333
    928      insn_lload_1:
     1334    insn_lload_1:
    9291335      LOADL (1);
    9301336      NEXT_INSN;
    9311337
    932      insn_lload_2:
     1338    insn_lload_2:
    9331339      LOADL (2);
    9341340      NEXT_INSN;
    9351341
    936      insn_lload_3:
     1342    insn_lload_3:
    9371343      LOADL (3);
    9381344      NEXT_INSN;
    9391345
    940      insn_fload_0:
     1346    insn_fload_0:
    9411347      LOADF (0);
    9421348      NEXT_INSN;
    9431349
    944      insn_fload_1:
     1350    insn_fload_1:
    9451351      LOADF (1);
    9461352      NEXT_INSN;
    9471353
    948      insn_fload_2:
     1354    insn_fload_2:
    9491355      LOADF (2);
    9501356      NEXT_INSN;
    9511357
    952      insn_fload_3:
     1358    insn_fload_3:
    9531359      LOADF (3);
    9541360      NEXT_INSN;
    9551361
    956      insn_dload_0:
     1362    insn_dload_0:
    9571363      LOADD (0);
    9581364      NEXT_INSN;
    9591365
    960      insn_dload_1:
     1366    insn_dload_1:
    9611367      LOADD (1);
    9621368      NEXT_INSN;
    9631369
    964      insn_dload_2:
     1370    insn_dload_2:
    9651371      LOADD (2);
    9661372      NEXT_INSN;
    9671373
    968      insn_dload_3:
     1374    insn_dload_3:
    9691375      LOADD (3);
    9701376      NEXT_INSN;
    9711377
    972      insn_aload_1:
     1378    insn_aload_1:
    9731379      LOADA(1);
    9741380      NEXT_INSN;
    9751381
    976      insn_aload_2:
     1382    insn_aload_2:
    9771383      LOADA(2);
    9781384      NEXT_INSN;
    9791385
    980      insn_aload_3:
     1386    insn_aload_3:
    9811387      LOADA(3);
    9821388      NEXT_INSN;
    9831389
    984      insn_iaload:
     1390    insn_iaload:
    9851391      {
    9861392        jint index = POPI();
     
    9921398      NEXT_INSN;
    9931399
    994      insn_laload:
     1400    insn_laload:
    9951401      {
    9961402        jint index = POPI();
     
    10021408      NEXT_INSN;
    10031409
    1004      insn_faload:
     1410    insn_faload:
    10051411      {
    10061412        jint index = POPI();
     
    10121418      NEXT_INSN;
    10131419
    1014      insn_daload:
     1420    insn_daload:
    10151421      {
    10161422        jint index = POPI();
     
    10221428      NEXT_INSN;
    10231429
    1024      insn_aaload:
     1430    insn_aaload:
    10251431      {
    10261432        jint index = POPI();
     
    10321438      NEXT_INSN;
    10331439
    1034      insn_baload:
     1440    insn_baload:
    10351441      {
    10361442        jint index = POPI();
     
    10421448      NEXT_INSN;
    10431449
    1044      insn_caload:
     1450    insn_caload:
    10451451      {
    10461452        jint index = POPI();
     
    10521458      NEXT_INSN;
    10531459
    1054      insn_saload:
     1460    insn_saload:
    10551461      {
    10561462        jint index = POPI();
     
    10621468      NEXT_INSN;
    10631469
    1064      insn_istore:
    1065       STOREI (get1u (pc++));
    1066       NEXT_INSN;
    1067 
    1068      insn_lstore:
    1069       STOREL (get1u (pc++));
    1070       NEXT_INSN;
    1071 
    1072      insn_fstore:
    1073       STOREF (get1u (pc++));
    1074       NEXT_INSN;
    1075 
    1076      insn_dstore:
    1077       STORED (get1u (pc++));
    1078       NEXT_INSN;
    1079 
    1080      insn_astore:
    1081       STOREA (get1u (pc++));
    1082       NEXT_INSN;
    1083 
    1084      insn_istore_0:
     1470    insn_istore:
     1471      STOREI (GET1U ());
     1472      NEXT_INSN;
     1473
     1474    insn_lstore:
     1475      STOREL (GET1U ());
     1476      NEXT_INSN;
     1477
     1478    insn_fstore:
     1479      STOREF (GET1U ());
     1480      NEXT_INSN;
     1481
     1482    insn_dstore:
     1483      STORED (GET1U ());
     1484      NEXT_INSN;
     1485
     1486    insn_astore:
     1487      STOREA (GET1U ());
     1488      NEXT_INSN;
     1489
     1490    insn_istore_0:
    10851491      STOREI (0);
    10861492      NEXT_INSN;
    10871493
    1088      insn_istore_1:
     1494    insn_istore_1:
    10891495      STOREI (1);
    10901496      NEXT_INSN;
    10911497
    1092      insn_istore_2:
     1498    insn_istore_2:
    10931499      STOREI (2);
    10941500      NEXT_INSN;
    10951501
    1096      insn_istore_3:
     1502    insn_istore_3:
    10971503      STOREI (3);
    10981504      NEXT_INSN;
    10991505
    1100      insn_lstore_0:
     1506    insn_lstore_0:
    11011507      STOREL (0);
    11021508      NEXT_INSN;
    11031509
    1104      insn_lstore_1:
     1510    insn_lstore_1:
    11051511      STOREL (1);
    11061512      NEXT_INSN;
    11071513
    1108      insn_lstore_2:
     1514    insn_lstore_2:
    11091515      STOREL (2);
    11101516      NEXT_INSN;
    11111517
    1112      insn_lstore_3:
     1518    insn_lstore_3:
    11131519      STOREL (3);
    11141520      NEXT_INSN;
    11151521
    1116      insn_fstore_0:
     1522    insn_fstore_0:
    11171523      STOREF (0);
    11181524      NEXT_INSN;
    11191525
    1120      insn_fstore_1:
     1526    insn_fstore_1:
    11211527      STOREF (1);
    11221528      NEXT_INSN;
    11231529
    1124      insn_fstore_2:
     1530    insn_fstore_2:
    11251531      STOREF (2);
    11261532      NEXT_INSN;
    11271533
    1128      insn_fstore_3:
     1534    insn_fstore_3:
    11291535      STOREF (3);
    11301536      NEXT_INSN;
    11311537
    1132      insn_dstore_0:
     1538    insn_dstore_0:
    11331539      STORED (0);
    11341540      NEXT_INSN;
    11351541
    1136      insn_dstore_1:
     1542    insn_dstore_1:
    11371543      STORED (1);
    11381544      NEXT_INSN;
    11391545
    1140      insn_dstore_2:
     1546    insn_dstore_2:
    11411547      STORED (2);
    11421548      NEXT_INSN;
    11431549
    1144      insn_dstore_3:
     1550    insn_dstore_3:
    11451551      STORED (3);
    11461552      NEXT_INSN;
    11471553
    1148      insn_astore_0:
     1554    insn_astore_0:
    11491555      STOREA(0);
    11501556      NEXT_INSN;
    11511557
    1152      insn_astore_1:
     1558    insn_astore_1:
    11531559      STOREA(1);
    11541560      NEXT_INSN;
    11551561
    1156      insn_astore_2:
     1562    insn_astore_2:
    11571563      STOREA(2);
    11581564      NEXT_INSN;
    11591565
    1160      insn_astore_3:
     1566    insn_astore_3:
    11611567      STOREA(3);
    11621568      NEXT_INSN;
    11631569
    1164      insn_iastore:
     1570    insn_iastore:
    11651571      {
    11661572        jint value = POPI();
     
    11731579      NEXT_INSN;
    11741580
    1175      insn_lastore:
     1581    insn_lastore:
    11761582      {
    11771583        jlong value = POPL();
     
    11841590      NEXT_INSN;
    11851591
    1186      insn_fastore:
     1592    insn_fastore:
    11871593      {
    11881594        jfloat value = POPF();
     
    11951601      NEXT_INSN;
    11961602
    1197      insn_dastore:
     1603    insn_dastore:
    11981604      {
    11991605        jdouble value = POPD();
     
    12061612      NEXT_INSN;
    12071613
    1208      insn_aastore:
     1614    insn_aastore:
    12091615      {
    12101616        jobject value = POPA();
     
    12181624      NEXT_INSN;
    12191625
    1220      insn_bastore:
     1626    insn_bastore:
    12211627      {
    12221628        jbyte value = (jbyte) POPI();
     
    12291635      NEXT_INSN;
    12301636
    1231      insn_castore:
     1637    insn_castore:
    12321638      {
    12331639        jchar value = (jchar) POPI();
     
    12401646      NEXT_INSN;
    12411647
    1242      insn_sastore:
     1648    insn_sastore:
    12431649      {
    12441650        jshort value = (jshort) POPI();
     
    12511657      NEXT_INSN;
    12521658
    1253      insn_pop:
     1659    insn_pop:
    12541660      sp -= 1;
    12551661      NEXT_INSN;
    12561662
    1257      insn_pop2:
     1663    insn_pop2:
    12581664      sp -= 2;
    12591665      NEXT_INSN;
    12601666
    1261      insn_dup:
     1667    insn_dup:
    12621668      sp[0] = sp[-1];
    12631669      sp += 1;
    12641670      NEXT_INSN;
    12651671
    1266      insn_dup_x1:
     1672    insn_dup_x1:
    12671673      dupx (sp, 1, 1); sp+=1;
    12681674      NEXT_INSN;
    12691675
    1270      insn_dup_x2:
     1676    insn_dup_x2:
    12711677      dupx (sp, 1, 2); sp+=1;
    12721678      NEXT_INSN;
    12731679
    1274      insn_dup2:
     1680    insn_dup2:
    12751681      sp[0] = sp[-2];
    12761682      sp[1] = sp[-1];
     
    12781684      NEXT_INSN;
    12791685
    1280      insn_dup2_x1:
     1686    insn_dup2_x1:
    12811687      dupx (sp, 2, 1); sp+=2;
    12821688      NEXT_INSN;
    12831689
    1284      insn_dup2_x2:
     1690    insn_dup2_x2:
    12851691      dupx (sp, 2, 2); sp+=2;
    12861692      NEXT_INSN;
    12871693
    1288      insn_swap:
     1694    insn_swap:
    12891695      {
    12901696        jobject tmp1 = POPA();
     
    12951701      NEXT_INSN;
    12961702
    1297      insn_iadd:
     1703    insn_iadd:
    12981704      BINOPI(+);
    12991705      NEXT_INSN;
    13001706
    1301      insn_ladd:
     1707    insn_ladd:
    13021708      BINOPL(+);
    13031709      NEXT_INSN;
    13041710
    1305      insn_fadd:
     1711    insn_fadd:
    13061712      BINOPF(+);
    13071713      NEXT_INSN;
    13081714
    1309      insn_dadd:
     1715    insn_dadd:
    13101716      BINOPD(+);
    13111717      NEXT_INSN;
    13121718
    1313      insn_isub:
     1719    insn_isub:
    13141720      BINOPI(-);
    13151721      NEXT_INSN;
    13161722
    1317      insn_lsub:
     1723    insn_lsub:
    13181724      BINOPL(-);
    13191725      NEXT_INSN;
    13201726
    1321      insn_fsub:
     1727    insn_fsub:
    13221728      BINOPF(-);
    13231729      NEXT_INSN;
    13241730
    1325      insn_dsub:
     1731    insn_dsub:
    13261732      BINOPD(-);
    13271733      NEXT_INSN;
    13281734
    1329      insn_imul:
     1735    insn_imul:
    13301736      BINOPI(*);
    13311737      NEXT_INSN;
    13321738
    1333      insn_lmul:
     1739    insn_lmul:
    13341740      BINOPL(*);
    13351741      NEXT_INSN;
    13361742
    1337      insn_fmul:
     1743    insn_fmul:
    13381744      BINOPF(*);
    13391745      NEXT_INSN;
    13401746
    1341      insn_dmul:
     1747    insn_dmul:
    13421748      BINOPD(*);
    13431749      NEXT_INSN;
    13441750
    1345      insn_idiv:
    1346       SAVE_PC;
     1751    insn_idiv:
    13471752      {
    13481753        jint value2 = POPI();
     
    13531758      NEXT_INSN;
    13541759
    1355      insn_ldiv:
    1356       SAVE_PC;
     1760    insn_ldiv:
    13571761      {
    13581762        jlong value2 = POPL();
     
    13631767      NEXT_INSN;
    13641768
    1365      insn_fdiv:
     1769    insn_fdiv:
    13661770      {
    13671771        jfloat value2 = POPF();
     
    13721776      NEXT_INSN;
    13731777
    1374      insn_ddiv:
     1778    insn_ddiv:
    13751779      {
    13761780        jdouble value2 = POPD();
     
    13811785      NEXT_INSN;
    13821786
    1383      insn_irem:
    1384       SAVE_PC;
     1787    insn_irem:
    13851788      {
    13861789        jint value2 = POPI();
     
    13911794      NEXT_INSN;
    13921795
    1393      insn_lrem:
    1394       SAVE_PC;
     1796    insn_lrem:
    13951797      {
    13961798        jlong value2 = POPL();
     
    14011803      NEXT_INSN;
    14021804
    1403      insn_frem:
     1805    insn_frem:
    14041806      {
    14051807        jfloat value2 = POPF();
     
    14101812      NEXT_INSN;
    14111813
    1412      insn_drem:
     1814    insn_drem:
    14131815      {
    14141816        jdouble value2 = POPD();
     
    14191821      NEXT_INSN;
    14201822
    1421      insn_ineg:
     1823    insn_ineg:
    14221824      {
    14231825        jint value = POPI();
     
    14261828      NEXT_INSN;
    14271829
    1428      insn_lneg:
     1830    insn_lneg:
    14291831      {
    14301832        jlong value = POPL();
     
    14331835      NEXT_INSN;
    14341836
    1435      insn_fneg:
     1837    insn_fneg:
    14361838      {
    14371839        jfloat value = POPF();
     
    14401842      NEXT_INSN;
    14411843
    1442      insn_dneg:
     1844    insn_dneg:
    14431845      {
    14441846        jdouble value = POPD();
     
    14471849      NEXT_INSN;
    14481850
    1449      insn_ishl:
     1851    insn_ishl:
    14501852      {
    14511853        jint shift = (POPI() & 0x1f);
     
    14551857      NEXT_INSN;
    14561858
    1457      insn_lshl:
     1859    insn_lshl:
    14581860      {
    14591861        jint shift = (POPI() & 0x3f);
     
    14631865      NEXT_INSN;
    14641866
    1465      insn_ishr:
     1867    insn_ishr:
    14661868      {
    14671869        jint shift = (POPI() & 0x1f);
     
    14711873      NEXT_INSN;
    14721874
    1473      insn_lshr:
     1875    insn_lshr:
    14741876      {
    14751877        jint shift = (POPI() & 0x3f);
     
    14791881      NEXT_INSN;
    14801882
    1481      insn_iushr:
     1883    insn_iushr:
    14821884      {
    14831885        jint shift = (POPI() & 0x1f);
    1484         unsigned long value = POPI();
     1886        UINT32 value = (UINT32) POPI();
    14851887        PUSHI ((jint) (value >> shift));
    14861888      }
    14871889      NEXT_INSN;
    14881890
    1489      insn_lushr:
     1891    insn_lushr:
    14901892      {
    14911893        jint shift = (POPI() & 0x3f);
     
    14951897      NEXT_INSN;
    14961898
    1497      insn_iand:
     1899    insn_iand:
    14981900      BINOPI (&);
    14991901      NEXT_INSN;
    15001902
    1501      insn_land:
     1903    insn_land:
    15021904      BINOPL (&);
    15031905      NEXT_INSN;
    15041906
    1505      insn_ior:
     1907    insn_ior:
    15061908      BINOPI (|);
    15071909      NEXT_INSN;
    15081910
    1509      insn_lor:
     1911    insn_lor:
    15101912      BINOPL (|);
    15111913      NEXT_INSN;
    15121914
    1513      insn_ixor:
     1915    insn_ixor:
    15141916      BINOPI (^);
    15151917      NEXT_INSN;
    15161918
    1517      insn_lxor:
     1919    insn_lxor:
    15181920      BINOPL (^);
    15191921      NEXT_INSN;
    15201922
    1521      insn_iinc:
    1522       {
    1523         jint index  = get1u (pc++);
    1524         jint amount = get1s (pc++);
     1923    insn_iinc:
     1924      {
     1925        jint index  = GET1U ();
     1926        jint amount = GET1S ();
    15251927        locals[index].i += amount;
    15261928      }
    15271929      NEXT_INSN;
    15281930
    1529      insn_i2l:
     1931    insn_i2l:
    15301932      {jlong value = POPI(); PUSHL (value);}
    15311933      NEXT_INSN;
    15321934
    1533      insn_i2f:
     1935    insn_i2f:
    15341936      {jfloat value = POPI(); PUSHF (value);}
    15351937      NEXT_INSN;
    15361938
    1537      insn_i2d:
     1939    insn_i2d:
    15381940      {jdouble value = POPI(); PUSHD (value);}
    15391941      NEXT_INSN;
    15401942
    1541      insn_l2i:
     1943    insn_l2i:
    15421944      {jint value = POPL(); PUSHI (value);}
    15431945      NEXT_INSN;
    15441946
    1545      insn_l2f:
     1947    insn_l2f:
    15461948      {jfloat value = POPL(); PUSHF (value);}
    15471949      NEXT_INSN;
    15481950
    1549      insn_l2d:
     1951    insn_l2d:
    15501952      {jdouble value = POPL(); PUSHD (value);}
    15511953      NEXT_INSN;
    15521954
    1553      insn_f2i:
     1955    insn_f2i:
    15541956      {
    15551957        using namespace java::lang;
     
    15591961      NEXT_INSN;
    15601962
    1561      insn_f2l:
     1963    insn_f2l:
    15621964      {
    15631965        using namespace java::lang;
     
    15671969      NEXT_INSN;
    15681970
    1569      insn_f2d:
     1971    insn_f2d:
    15701972      { jdouble value = POPF (); PUSHD(value); }
    15711973      NEXT_INSN;
    15721974
    1573      insn_d2i:
     1975    insn_d2i:
    15741976      {
    15751977        using namespace java::lang;
     
    15791981      NEXT_INSN;
    15801982
    1581      insn_d2l:
     1983    insn_d2l:
    15821984      {
    15831985        using namespace java::lang;
     
    15871989      NEXT_INSN;
    15881990
    1589      insn_d2f:
     1991    insn_d2f:
    15901992      { jfloat value = POPD (); PUSHF(value); }
    15911993      NEXT_INSN;
    15921994
    1593      insn_i2b:
     1995    insn_i2b:
    15941996      { jbyte value = POPI (); PUSHI(value); }
    15951997      NEXT_INSN;
    15961998
    1597      insn_i2c:
     1999    insn_i2c:
    15982000      { jchar value = POPI (); PUSHI(value); }
    15992001      NEXT_INSN;
    16002002
    1601      insn_i2s:
     2003    insn_i2s:
    16022004      { jshort value = POPI (); PUSHI(value); }
    16032005      NEXT_INSN;
    16042006
    1605      insn_lcmp:
     2007    insn_lcmp:
    16062008      {
    16072009        jlong value2 = POPL ();
     
    16162018      NEXT_INSN;
    16172019
    1618      insn_fcmpl:
    1619      insn_fcmpg:
     2020    insn_fcmpl:
     2021      tmpval = -1;
     2022      goto fcmp;
     2023
     2024    insn_fcmpg:
     2025      tmpval = 1;
     2026
     2027    fcmp:
    16202028      {
    16212029        jfloat value2 = POPF ();
     
    16272035        else if (value1 < value2)
    16282036          PUSHI (-1);
    1629         else if ((*(pc-1)) == op_fcmpg)
    1630           PUSHI (1);
    16312037        else
    1632           PUSHI (-1);
    1633       }
    1634       NEXT_INSN;
    1635 
    1636      insn_dcmpl:
    1637      insn_dcmpg:
     2038          PUSHI (tmpval);
     2039      }
     2040      NEXT_INSN;
     2041
     2042    insn_dcmpl:
     2043      tmpval = 1;
     2044      goto dcmp;
     2045
     2046    insn_dcmpg:
     2047      tmpval = -1;
     2048
     2049    dcmp:
    16382050      {
    16392051        jdouble value2 = POPD ();
     
    16452057        else if (value1 < value2)
    16462058          PUSHI (-1);
    1647         else if ((*(pc-1)) == op_dcmpg)
    1648           PUSHI (1);
    16492059        else
    1650           PUSHI (-1);
    1651       }
    1652       NEXT_INSN;
    1653 
    1654      insn_ifeq:
    1655       {
    1656         jint offset = get2s (pc);
     2060          PUSHI (tmpval);
     2061      }
     2062      NEXT_INSN;
     2063
     2064    insn_ifeq:
     2065      {
    16572066        if (POPI() == 0)
    1658           pc = pc-1+offset;
     2067          TAKE_GOTO;
    16592068        else
    1660           pc = pc+2;
    1661       }
    1662       NEXT_INSN;
    1663 
    1664      insn_ifne:
    1665       {
    1666         jint offset = get2s (pc);
     2069          SKIP_GOTO;
     2070      }
     2071      NEXT_INSN;
     2072
     2073    insn_ifne:
     2074      {
    16672075        if (POPI() != 0)
    1668           pc = pc-1+offset;
     2076          TAKE_GOTO;
    16692077        else
    1670           pc = pc+2;
    1671       }
    1672       NEXT_INSN;
    1673 
    1674      insn_iflt:
    1675       {
    1676         jint offset = get2s (pc);
     2078          SKIP_GOTO;
     2079      }
     2080      NEXT_INSN;
     2081
     2082    insn_iflt:
     2083      {
    16772084        if (POPI() < 0)
    1678           pc = pc-1+offset;
     2085          TAKE_GOTO;
    16792086        else
    1680           pc = pc+2;
    1681       }
    1682       NEXT_INSN;
    1683 
    1684      insn_ifge:
    1685       {
    1686         jint offset = get2s (pc);
     2087          SKIP_GOTO;
     2088      }
     2089      NEXT_INSN;
     2090
     2091    insn_ifge:
     2092      {
    16872093        if (POPI() >= 0)
    1688           pc = pc-1+offset;
     2094          TAKE_GOTO;
    16892095        else
    1690           pc = pc+2;
    1691       }
    1692       NEXT_INSN;
    1693 
    1694      insn_ifgt:
    1695       {
    1696         jint offset = get2s (pc);
     2096          SKIP_GOTO;
     2097      }
     2098      NEXT_INSN;
     2099
     2100    insn_ifgt:
     2101      {
    16972102        if (POPI() > 0)
    1698           pc = pc-1+offset;
     2103          TAKE_GOTO;
    16992104        else
    1700           pc = pc+2;
    1701       }
    1702       NEXT_INSN;
    1703 
    1704      insn_ifle:
    1705       {
    1706         jint offset = get2s (pc);
     2105          SKIP_GOTO;
     2106      }
     2107      NEXT_INSN;
     2108
     2109    insn_ifle:
     2110      {
    17072111        if (POPI() <= 0)
    1708           pc = pc-1+offset;
     2112          TAKE_GOTO;
    17092113        else
    1710           pc = pc+2;
    1711       }
    1712       NEXT_INSN;
    1713 
    1714      insn_if_icmpeq:
    1715       {
    1716         jint offset = get2s (pc);
     2114          SKIP_GOTO;
     2115      }
     2116      NEXT_INSN;
     2117
     2118    insn_if_icmpeq:
     2119      {
    17172120        jint value2 = POPI();
    17182121        jint value1 = POPI();
    17192122        if (value1 == value2)
    1720           pc = pc-1+offset;
     2123          TAKE_GOTO;
    17212124        else
    1722           pc = pc+2;
    1723       }
    1724       NEXT_INSN;
    1725 
    1726      insn_if_icmpne:
    1727       {
    1728         jint offset = get2s (pc);
     2125          SKIP_GOTO;
     2126      }
     2127      NEXT_INSN;
     2128
     2129    insn_if_icmpne:
     2130      {
    17292131        jint value2 = POPI();
    17302132        jint value1 = POPI();
    17312133        if (value1 != value2)
    1732           pc = pc-1+offset;
     2134          TAKE_GOTO;
    17332135        else
    1734           pc = pc+2;
    1735       }
    1736       NEXT_INSN;
    1737 
    1738      insn_if_icmplt:
    1739       {
    1740         jint offset = get2s (pc);
     2136          SKIP_GOTO;
     2137      }
     2138      NEXT_INSN;
     2139
     2140    insn_if_icmplt:
     2141      {
    17412142        jint value2 = POPI();
    17422143        jint value1 = POPI();
    17432144        if (value1 < value2)
    1744           pc = pc-1+offset;
     2145          TAKE_GOTO;
    17452146        else
    1746           pc = pc+2;
    1747       }
    1748       NEXT_INSN;
    1749 
    1750      insn_if_icmpge:
    1751       {
    1752         jint offset = get2s (pc);
     2147          SKIP_GOTO;
     2148      }
     2149      NEXT_INSN;
     2150
     2151    insn_if_icmpge:
     2152      {
    17532153        jint value2 = POPI();
    17542154        jint value1 = POPI();
    17552155        if (value1 >= value2)
    1756           pc = pc-1+offset;
     2156          TAKE_GOTO;
    17572157        else
    1758           pc = pc+2;
    1759       }
    1760       NEXT_INSN;
    1761 
    1762      insn_if_icmpgt:
    1763       {
    1764         jint offset = get2s (pc);
     2158          SKIP_GOTO;
     2159      }
     2160      NEXT_INSN;
     2161
     2162    insn_if_icmpgt:
     2163      {
    17652164        jint value2 = POPI();
    17662165        jint value1 = POPI();
    17672166        if (value1 > value2)
    1768           pc = pc-1+offset;
     2167          TAKE_GOTO;
    17692168        else
    1770           pc = pc+2;
    1771       }
    1772       NEXT_INSN;
    1773 
    1774      insn_if_icmple:
    1775       {
    1776         jint offset = get2s (pc);
     2169          SKIP_GOTO;
     2170      }
     2171      NEXT_INSN;
     2172
     2173    insn_if_icmple:
     2174      {
    17772175        jint value2 = POPI();
    17782176        jint value1 = POPI();
    17792177        if (value1 <= value2)
    1780           pc = pc-1+offset;
     2178          TAKE_GOTO;
    17812179        else
    1782           pc = pc+2;
    1783       }
    1784       NEXT_INSN;
    1785 
    1786      insn_if_acmpeq:
    1787       {
    1788         jint offset = get2s (pc);
     2180          SKIP_GOTO;
     2181      }
     2182      NEXT_INSN;
     2183
     2184    insn_if_acmpeq:
     2185      {
    17892186        jobject value2 = POPA();
    17902187        jobject value1 = POPA();
    17912188        if (value1 == value2)
    1792           pc = pc-1+offset;
     2189          TAKE_GOTO;
    17932190        else
    1794           pc = pc+2;
    1795       }
    1796       NEXT_INSN;
    1797 
    1798      insn_if_acmpne:
    1799       {
    1800         jint offset = get2s (pc);
     2191          SKIP_GOTO;
     2192      }
     2193      NEXT_INSN;
     2194
     2195    insn_if_acmpne:
     2196      {
    18012197        jobject value2 = POPA();
    18022198        jobject value1 = POPA();
    18032199        if (value1 != value2)
    1804           pc = pc-1+offset;
     2200          TAKE_GOTO;
    18052201        else
    1806           pc = pc+2;
    1807       }
    1808       NEXT_INSN;
    1809 
    1810      insn_goto:
    1811       {
    1812         jint offset = get2s (pc);
    1813         pc = pc-1+offset;
    1814       }
    1815       NEXT_INSN;
    1816 
    1817      insn_jsr:
    1818       {
    1819         unsigned char *base_pc = pc-1;
    1820         jint offset = get2s (pc); pc += 2;
    1821         PUSHA ((jobject)pc);
    1822         pc = base_pc+offset;
    1823       }
    1824       NEXT_INSN;
    1825 
    1826      insn_ret:
    1827       {
    1828         jint index = get1u (pc);
    1829         pc = (unsigned char*) PEEKA (index);
    1830       }
    1831       NEXT_INSN;
    1832 
    1833      insn_tableswitch:
    1834       {
     2202          SKIP_GOTO;
     2203      }
     2204      NEXT_INSN;
     2205
     2206    insn_goto_w:
     2207#ifndef DIRECT_THREADED
     2208      // For direct threaded, goto and goto_w are the same.
     2209      pc = pc - 1 + get4 (pc);
     2210      NEXT_INSN;
     2211#endif /* DIRECT_THREADED */
     2212    insn_goto:
     2213      TAKE_GOTO;
     2214      NEXT_INSN;
     2215
     2216    insn_jsr_w:
     2217#ifndef DIRECT_THREADED
     2218      // For direct threaded, jsr and jsr_w are the same.
     2219      {
     2220        pc_t next = pc - 1 + get4 (pc);
     2221        pc += 4;
     2222        PUSHA ((jobject) pc);
     2223        pc = next;
     2224      }
     2225      NEXT_INSN;
     2226#endif /* DIRECT_THREADED */
     2227    insn_jsr:
     2228      {
     2229        pc_t next = GOTO_VAL();
     2230        SKIP_GOTO;
     2231        PUSHA ((jobject) pc);
     2232        pc = next;
     2233      }
     2234      NEXT_INSN;
     2235
     2236    insn_ret:
     2237      {
     2238        jint index = GET1U ();
     2239        pc = (pc_t) PEEKA (index);
     2240      }
     2241      NEXT_INSN;
     2242
     2243    insn_tableswitch:
     2244      {
     2245#ifdef DIRECT_THREADED
     2246        void *def = (pc++)->datum;
     2247
     2248        int index = POPI();
     2249
     2250        jint low = INTVAL ();
     2251        jint high = INTVAL ();
     2252
     2253        if (index < low || index > high)
     2254          pc = (insn_slot *) def;
     2255        else
     2256          pc = (insn_slot *) ((pc + index - low)->datum);
     2257#else
     2258        pc_t base_pc = pc - 1;
     2259        int index = POPI ();
     2260
     2261        pc_t base = (pc_t) bytecode ();
     2262        while ((pc - base) % 4 != 0)
     2263          ++pc;
     2264
     2265        jint def = get4 (pc);
     2266        jint low = get4 (pc + 4);
     2267        jint high = get4 (pc + 8);
     2268        if (index < low || index > high)
     2269          pc = base_pc + def;
     2270        else
     2271          pc = base_pc + get4 (pc + 4 * (index - low + 3));
     2272#endif /* DIRECT_THREADED */
     2273      }
     2274      NEXT_INSN;
     2275
     2276    insn_lookupswitch:
     2277      {
     2278#ifdef DIRECT_THREADED
     2279        void *def = (pc++)->insn;
     2280
     2281        int index = POPI();
     2282
     2283        jint npairs = INTVAL ();
     2284
     2285        int max = npairs - 1;
     2286        int min = 0;
     2287
     2288        // Simple binary search...
     2289        while (min < max)
     2290          {
     2291            int half = (min + max) / 2;
     2292            int match = pc[2 * half].int_val;
     2293
     2294            if (index == match)
     2295              {
     2296                // Found it.
     2297                pc = (insn_slot *) pc[2 * half + 1].datum;
     2298                NEXT_INSN;
     2299              }
     2300            else if (index < match)
     2301              // We can use HALF - 1 here because we check again on
     2302              // loop exit.
     2303              max = half - 1;
     2304            else
     2305              // We can use HALF + 1 here because we check again on
     2306              // loop exit.
     2307              min = half + 1;
     2308          }
     2309        if (index == pc[2 * min].int_val)
     2310          pc = (insn_slot *) pc[2 * min + 1].datum;
     2311        else
     2312          pc = (insn_slot *) def;
     2313#else
    18352314        unsigned char *base_pc = pc-1;
    18362315        int index = POPI();
     
    18382317        unsigned char* base = bytecode ();
    18392318        while ((pc-base) % 4 != 0)
    1840           pc++;
    1841 
    1842         jint def     = get4 (pc);
    1843         jint low     = get4 (pc+4);
    1844         jint high    = get4 (pc+8);
    1845 
    1846         if (index < low || index > high)
    1847           pc = base_pc + def;   
    1848         else
    1849           pc = base_pc + get4 (pc+4*(index-low+3));
    1850       }
    1851       NEXT_INSN;
    1852 
    1853      insn_lookupswitch:
    1854       {
    1855         unsigned char *base_pc = pc-1;
    1856         int index = POPI();
    1857 
    1858         unsigned char* base = bytecode ();
    1859         while ((pc-base) % 4 != 0)
    1860           pc++;
     2319          ++pc;
    18612320
    18622321        jint def     = get4 (pc);
     
    18662325        int min = 0;
    18672326
    1868         // simple binary search...
     2327        // Simple binary search...
    18692328        while (min < max)
    18702329          {
     
    18742333            if (index == match)
    18752334              min = max = half;
    1876 
    18772335            else if (index < match)
    1878               max = half-1;
    1879 
     2336              // We can use HALF - 1 here because we check again on
     2337              // loop exit.
     2338              max = half - 1;
    18802339            else
    1881               min = half+1;
     2340              // We can use HALF + 1 here because we check again on
     2341              // loop exit.
     2342              min = half + 1;
    18822343          }
    18832344
     
    18862347        else
    18872348          pc = base_pc + def;   
    1888       }
    1889       NEXT_INSN;
    1890 
    1891       /* on return, just save the sp and return to caller */
    1892      insn_ireturn:
    1893      insn_lreturn:
    1894      insn_freturn:
    1895      insn_dreturn:
    1896      insn_areturn:
    1897      insn_return:
    1898       inv->sp = sp;
     2349#endif /* DIRECT_THREADED */
     2350      }
     2351      NEXT_INSN;
     2352
     2353    insn_areturn:
     2354      *(jobject *) retp = POPA ();
    18992355      return;
    19002356
    1901      insn_getstatic:
    1902       SAVE_PC;
    1903       {
    1904         jint fieldref_index = get2u (pc); pc += 2;
     2357    insn_lreturn:
     2358      *(jlong *) retp = POPL ();
     2359      return;
     2360
     2361    insn_freturn:
     2362      *(jfloat *) retp = POPF ();
     2363      return;
     2364
     2365    insn_dreturn:
     2366      *(jdouble *) retp = POPD ();
     2367      return;
     2368
     2369    insn_ireturn:
     2370      *(jint *) retp = POPI ();
     2371      return;
     2372
     2373    insn_return:
     2374      return;
     2375
     2376    insn_getstatic:
     2377      {
     2378        jint fieldref_index = GET2U ();
    19052379        _Jv_ResolvePoolEntry (defining_class, fieldref_index);
    19062380        _Jv_Field *field = pool_data[fieldref_index].field;
     
    19122386        jclass type = field->type;
    19132387
     2388        // We rewrite the instruction once we discover what it refers
     2389        // to.
     2390        void *newinsn = NULL;
    19142391        if (type->isPrimitive ())
    19152392          {
     
    19182395              case 1:
    19192396                PUSHI (*(jbyte*) (field->u.addr));
     2397                newinsn = AMPAMP (getstatic_resolved_1);
    19202398                break;
    19212399
    19222400              case 2:
    19232401                if (type == JvPrimClass (char))
    1924                   PUSHI(*(jchar*) (field->u.addr));
     2402                  {
     2403                    PUSHI(*(jchar*) (field->u.addr));
     2404                    newinsn = AMPAMP (getstatic_resolved_char);
     2405                  }
    19252406                else
    1926                   PUSHI(*(jshort*) (field->u.addr));
     2407                  {
     2408                    PUSHI(*(jshort*) (field->u.addr));
     2409                    newinsn = AMPAMP (getstatic_resolved_short);
     2410                  }
    19272411                break;
    19282412
    19292413              case 4:
    19302414                PUSHI(*(jint*) (field->u.addr));
     2415                newinsn = AMPAMP (getstatic_resolved_4);
    19312416                break;
    19322417
    19332418              case 8:
    19342419                PUSHL(*(jlong*) (field->u.addr));
     2420                newinsn = AMPAMP (getstatic_resolved_8);
    19352421                break;
    19362422              }
     
    19392425          {
    19402426            PUSHA(*(jobject*) (field->u.addr));
     2427            newinsn = AMPAMP (getstatic_resolved_obj);
    19412428          }
    1942       }
    1943       NEXT_INSN;
    1944 
    1945      insn_getfield:
    1946       SAVE_PC;
    1947       {
    1948         jint fieldref_index = get2u (pc); pc += 2;
     2429
     2430#ifdef DIRECT_THREADED
     2431        pc[-2].insn = newinsn;
     2432        pc[-1].datum = field->u.addr;
     2433#endif /* DIRECT_THREADED */
     2434      }
     2435      NEXT_INSN;
     2436
     2437#ifdef DIRECT_THREADED
     2438    getstatic_resolved_1:
     2439      PUSHI (*(jbyte *) AVAL ());
     2440      NEXT_INSN;
     2441
     2442    getstatic_resolved_char:
     2443      PUSHI (*(jchar *) AVAL ());
     2444      NEXT_INSN;
     2445
     2446    getstatic_resolved_short:
     2447      PUSHI (*(jshort *) AVAL ());
     2448      NEXT_INSN;
     2449
     2450    getstatic_resolved_4:
     2451      PUSHI (*(jint *) AVAL ());
     2452      NEXT_INSN;
     2453
     2454    getstatic_resolved_8:
     2455      PUSHL (*(jlong *) AVAL ());
     2456      NEXT_INSN;
     2457
     2458    getstatic_resolved_obj:
     2459      PUSHA (*(jobject *) AVAL ());
     2460      NEXT_INSN;
     2461#endif /* DIRECT_THREADED */
     2462
     2463    insn_getfield:
     2464      {
     2465        jint fieldref_index = GET2U ();
    19492466        _Jv_ResolvePoolEntry (defining_class, fieldref_index);
    19502467        _Jv_Field *field = pool_data[fieldref_index].field;
     
    19622479        NULLCHECK(obj);
    19632480
     2481        void *newinsn = NULL;
    19642482        if (type->isPrimitive ())
    19652483          {
     
    19682486              case 1:
    19692487                PUSHI (*(jbyte*) ((char*)obj + field_offset));
     2488                newinsn = AMPAMP (getfield_resolved_1);
    19702489                break;
    19712490
    19722491              case 2:
    19732492                if (type == JvPrimClass (char))
    1974                   PUSHI (*(jchar*) ((char*)obj + field_offset));
     2493                  {
     2494                    PUSHI (*(jchar*) ((char*)obj + field_offset));
     2495                    newinsn = AMPAMP (getfield_resolved_char);
     2496                  }
    19752497                else
    1976                   PUSHI (*(jshort*) ((char*)obj + field_offset));
     2498                  {
     2499                    PUSHI (*(jshort*) ((char*)obj + field_offset));
     2500                    newinsn = AMPAMP (getfield_resolved_short);
     2501                  }
    19772502                break;
    19782503
    19792504              case 4:
    19802505                PUSHI (*(jint*) ((char*)obj + field_offset));
     2506                newinsn = AMPAMP (getfield_resolved_4);
    19812507                break;
    19822508
    19832509              case 8:
    19842510                PUSHL(*(jlong*) ((char*)obj + field_offset));
     2511                newinsn = AMPAMP (getfield_resolved_8);
    19852512                break;
    19862513              }
     
    19892516          {
    19902517            PUSHA(*(jobject*) ((char*)obj + field_offset));
     2518            newinsn = AMPAMP (getfield_resolved_obj);
    19912519          }
    1992       }
    1993       NEXT_INSN;
    1994 
    1995      insn_putstatic:
    1996       SAVE_PC;
    1997       {
    1998         jint fieldref_index = get2u (pc); pc += 2;
     2520
     2521#ifdef DIRECT_THREADED
     2522        pc[-2].insn = newinsn;
     2523        pc[-1].int_val = field_offset;
     2524#endif /* DIRECT_THREADED */
     2525      }
     2526      NEXT_INSN;
     2527
     2528#ifdef DIRECT_THREADED
     2529    getfield_resolved_1:
     2530      {
     2531        char *obj = (char *) POPA ();
     2532        NULLCHECK (obj);
     2533        PUSHI (*(jbyte *) (obj + INTVAL ()));
     2534      }
     2535      NEXT_INSN;
     2536
     2537    getfield_resolved_char:
     2538      {
     2539        char *obj = (char *) POPA ();
     2540        NULLCHECK (obj);
     2541        PUSHI (*(jchar *) (obj + INTVAL ()));
     2542      }
     2543      NEXT_INSN;
     2544
     2545    getfield_resolved_short:
     2546      {
     2547        char *obj = (char *) POPA ();
     2548        NULLCHECK (obj);
     2549        PUSHI (*(jshort *) (obj + INTVAL ()));
     2550      }
     2551      NEXT_INSN;
     2552
     2553    getfield_resolved_4:
     2554      {
     2555        char *obj = (char *) POPA ();
     2556        NULLCHECK (obj);
     2557        PUSHI (*(jint *) (obj + INTVAL ()));
     2558      }
     2559      NEXT_INSN;
     2560
     2561    getfield_resolved_8:
     2562      {
     2563        char *obj = (char *) POPA ();
     2564        NULLCHECK (obj);
     2565        PUSHL (*(jlong *) (obj + INTVAL ()));
     2566      }
     2567      NEXT_INSN;
     2568
     2569    getfield_resolved_obj:
     2570      {
     2571        char *obj = (char *) POPA ();
     2572        NULLCHECK (obj);
     2573        PUSHA (*(jobject *) (obj + INTVAL ()));
     2574      }
     2575      NEXT_INSN;
     2576#endif /* DIRECT_THREADED */
     2577
     2578    insn_putstatic:
     2579      {
     2580        jint fieldref_index = GET2U ();
    19992581        _Jv_ResolvePoolEntry (defining_class, fieldref_index);
    20002582        _Jv_Field *field = pool_data[fieldref_index].field;
     
    20072589            (JvNewStringLatin1 ("field no longer static"));
    20082590
     2591        void *newinsn = NULL;
    20092592        if (type->isPrimitive ())
    20102593          {
     
    20152598                  jint value = POPI();
    20162599                  *(jbyte*) (field->u.addr) = value;
     2600                  newinsn = AMPAMP (putstatic_resolved_1);
    20172601                  break;
    20182602                }
     
    20222606                  jint value = POPI();
    20232607                  *(jchar*) (field->u.addr) = value;
     2608                  newinsn = AMPAMP (putstatic_resolved_2);
    20242609                  break;
    20252610                }
     
    20292614                  jint value = POPI();
    20302615                  *(jint*) (field->u.addr) = value;
     2616                  newinsn = AMPAMP (putstatic_resolved_4);
    20312617                  break;
    20322618                }
     
    20362622                  jlong value = POPL();
    20372623                  *(jlong*) (field->u.addr) = value;
     2624                  newinsn = AMPAMP (putstatic_resolved_8);
    20382625                  break;
    20392626                }
     
    20442631            jobject value = POPA();
    20452632            *(jobject*) (field->u.addr) = value;
     2633            newinsn = AMPAMP (putstatic_resolved_obj);
    20462634          }
    2047       }
    2048       NEXT_INSN;
    2049 
    2050 
    2051      insn_putfield:
    2052       SAVE_PC;
    2053       {
    2054         jint fieldref_index = get2u (pc); pc += 2;
     2635
     2636#ifdef DIRECT_THREADED
     2637        pc[-2].insn = newinsn;
     2638        pc[-1].datum = field->u.addr;
     2639#endif /* DIRECT_THREADED */
     2640      }
     2641      NEXT_INSN;
     2642
     2643#ifdef DIRECT_THREADED
     2644    putstatic_resolved_1:
     2645      *(jbyte *) AVAL () = POPI ();
     2646      NEXT_INSN;
     2647
     2648    putstatic_resolved_2:
     2649      *(jchar *) AVAL () = POPI ();
     2650      NEXT_INSN;
     2651
     2652    putstatic_resolved_4:
     2653      *(jint *) AVAL () = POPI ();
     2654      NEXT_INSN;
     2655
     2656    putstatic_resolved_8:
     2657      *(jlong *) AVAL () = POPL ();
     2658      NEXT_INSN;
     2659
     2660    putstatic_resolved_obj:
     2661      *(jobject *) AVAL () = POPA ();
     2662      NEXT_INSN;
     2663#endif /* DIRECT_THREADED */
     2664
     2665    insn_putfield:
     2666      {
     2667        jint fieldref_index = GET2U ();
    20552668        _Jv_ResolvePoolEntry (defining_class, fieldref_index);
    20562669        _Jv_Field *field = pool_data[fieldref_index].field;
     
    20662679          throw new java::lang::VirtualMachineError;
    20672680
     2681        void *newinsn = NULL;
    20682682        if (type->isPrimitive ())
    20692683          {
     
    20762690                  NULLCHECK(obj);
    20772691                  *(jbyte*) ((char*)obj + field_offset) = value;
     2692                  newinsn = AMPAMP (putfield_resolved_1);
    20782693                  break;
    20792694                }
     
    20852700                  NULLCHECK(obj);
    20862701                  *(jchar*) ((char*)obj + field_offset) = value;
     2702                  newinsn = AMPAMP (putfield_resolved_2);
    20872703                  break;
    20882704                }
     
    20942710                  NULLCHECK(obj);
    20952711                  *(jint*) ((char*)obj + field_offset) = value;
     2712                  newinsn = AMPAMP (putfield_resolved_4);
    20962713                  break;
    20972714                }
     
    21032720                  NULLCHECK(obj);
    21042721                  *(jlong*) ((char*)obj + field_offset) = value;
     2722                  newinsn = AMPAMP (putfield_resolved_8);
    21052723                  break;
    21062724                }
     
    21132731            NULLCHECK(obj);
    21142732            *(jobject*) ((char*)obj + field_offset) = value;
     2733            newinsn = AMPAMP (putfield_resolved_obj);
    21152734          }
    2116       }
    2117       NEXT_INSN;
    2118 
    2119      insn_invokespecial:
    2120       SAVE_PC;
    2121       {
    2122         int index = get2u (pc); pc += 2;
     2735
     2736#ifdef DIRECT_THREADED
     2737        pc[-2].insn = newinsn;
     2738        pc[-1].int_val = field_offset;
     2739#endif /* DIRECT_THREADED */
     2740      }
     2741      NEXT_INSN;
     2742
     2743#ifdef DIRECT_THREADED
     2744    putfield_resolved_1:
     2745      {
     2746        jint val = POPI ();
     2747        char *obj = (char *) POPA ();
     2748        NULLCHECK (obj);
     2749        *(jbyte *) (obj + INTVAL ()) = val;
     2750      }
     2751      NEXT_INSN;
     2752
     2753    putfield_resolved_2:
     2754      {
     2755        jint val = POPI ();
     2756        char *obj = (char *) POPA ();
     2757        NULLCHECK (obj);
     2758        *(jchar *) (obj + INTVAL ()) = val;
     2759      }
     2760      NEXT_INSN;
     2761
     2762    putfield_resolved_4:
     2763      {
     2764        jint val = POPI ();
     2765        char *obj = (char *) POPA ();
     2766        NULLCHECK (obj);
     2767        *(jint *) (obj + INTVAL ()) = val;
     2768      }
     2769      NEXT_INSN;
     2770
     2771    putfield_resolved_8:
     2772      {
     2773        jlong val = POPL ();
     2774        char *obj = (char *) POPA ();
     2775        NULLCHECK (obj);
     2776        *(jlong *) (obj + INTVAL ()) = val;
     2777      }
     2778      NEXT_INSN;
     2779
     2780    putfield_resolved_obj:
     2781      {
     2782        jobject val = POPA ();
     2783        char *obj = (char *) POPA ();
     2784        NULLCHECK (obj);
     2785        *(jobject *) (obj + INTVAL ()) = val;
     2786      }
     2787      NEXT_INSN;
     2788#endif /* DIRECT_THREADED */
     2789
     2790    insn_invokespecial:
     2791      {
     2792        int index = GET2U ();
    21232793
    21242794        rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
     
    21262796        sp -= rmeth->stack_item_count;
    21272797
    2128         NULLCHECK (sp[0].o);
     2798        // We don't use NULLCHECK here because we can't rely on that
     2799        // working for <init>.  So instead we do an explicit test.
     2800        if (! sp[0].o)
     2801          throw new java::lang::NullPointerException;
    21292802
    21302803        fun = (void (*)()) rmeth->method->ncode;
     2804
     2805#ifdef DIRECT_THREADED
     2806        // Rewrite instruction so that we use a faster pre-resolved
     2807        // method.
     2808        pc[-2].insn = &&invokespecial_resolved;
     2809        pc[-1].datum = rmeth;
     2810#endif /* DIRECT_THREADED */
    21312811      }
    21322812      goto perform_invoke;
    21332813
    2134      insn_invokestatic:
    2135       SAVE_PC;
    2136       {
    2137         int index = get2u (pc); pc += 2;
     2814#ifdef DIRECT_THREADED
     2815    invokespecial_resolved:
     2816      {
     2817        rmeth = (_Jv_ResolvedMethod *) AVAL ();
     2818        sp -= rmeth->stack_item_count;
     2819        // We don't use NULLCHECK here because we can't rely on that
     2820        // working for <init>.  So instead we do an explicit test.
     2821        if (! sp[0].o)
     2822          throw new java::lang::NullPointerException;
     2823        fun = (void (*)()) rmeth->method->ncode;
     2824      }
     2825      goto perform_invoke;
     2826#endif /* DIRECT_THREADED */
     2827
     2828    insn_invokestatic:
     2829      {
     2830        int index = GET2U ();
    21382831
    21392832        rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
     
    21432836        _Jv_InitClass (rmeth->klass);
    21442837        fun = (void (*)()) rmeth->method->ncode;
     2838
     2839#ifdef DIRECT_THREADED
     2840        // Rewrite instruction so that we use a faster pre-resolved
     2841        // method.
     2842        pc[-2].insn = &&invokestatic_resolved;
     2843        pc[-1].datum = rmeth;
     2844#endif /* DIRECT_THREADED */
    21452845      }
    21462846      goto perform_invoke;
    21472847
    2148      insn_invokeinterface:
    2149       SAVE_PC;
    2150       {
    2151         int index = get2u (pc); pc += 2;
    2152 
    2153         // invokeinterface has two unused bytes...
    2154         pc += 2;
     2848#ifdef DIRECT_THREADED
     2849    invokestatic_resolved:
     2850      {
     2851        rmeth = (_Jv_ResolvedMethod *) AVAL ();
     2852        sp -= rmeth->stack_item_count;
     2853        fun = (void (*)()) rmeth->method->ncode;
     2854      }
     2855      goto perform_invoke;
     2856#endif /* DIRECT_THREADED */
     2857
     2858    insn_invokeinterface:
     2859      {
     2860        int index = GET2U ();
    21552861
    21562862        rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
     
    21662872                                     rmeth->method->name,
    21672873                                     rmeth->method->signature);
     2874
     2875#ifdef DIRECT_THREADED
     2876        // Rewrite instruction so that we use a faster pre-resolved
     2877        // method.
     2878        pc[-2].insn = &&invokeinterface_resolved;
     2879        pc[-1].datum = rmeth;
     2880#else
     2881        // Skip dummy bytes.
     2882        pc += 2;
     2883#endif /* DIRECT_THREADED */
    21682884      }
    21692885      goto perform_invoke;
    21702886
    2171 
    2172      insn_new:
    2173       SAVE_PC;
    2174       {
    2175         int index = get2u (pc); pc += 2;
     2887#ifdef DIRECT_THREADED
     2888    invokeinterface_resolved:
     2889      {
     2890        rmeth = (_Jv_ResolvedMethod *) AVAL ();
     2891        sp -= rmeth->stack_item_count;
     2892        jobject rcv = sp[0].o;
     2893        NULLCHECK (rcv);
     2894        fun = (void (*)())
     2895          _Jv_LookupInterfaceMethod (rcv->getClass (),
     2896                                     rmeth->method->name,
     2897                                     rmeth->method->signature);
     2898      }
     2899      goto perform_invoke;
     2900#endif /* DIRECT_THREADED */
     2901
     2902    insn_new:
     2903      {
     2904        int index = GET2U ();
    21762905        jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
    21772906        _Jv_InitClass (klass);
    21782907        jobject res = _Jv_AllocObject (klass, klass->size_in_bytes);
    21792908        PUSHA (res);
    2180       }
    2181       NEXT_INSN;
    2182 
    2183      insn_newarray:
    2184       SAVE_PC;
    2185       {
    2186         int atype = get1u (pc++);
     2909
     2910#ifdef DIRECT_THREADED
     2911        pc[-2].insn = &&new_resolved;
     2912        pc[-1].datum = klass;
     2913#endif /* DIRECT_THREADED */
     2914      }
     2915      NEXT_INSN;
     2916
     2917#ifdef DIRECT_THREADED
     2918    new_resolved:
     2919      {
     2920        jclass klass = (jclass) AVAL ();
     2921        jobject res = _Jv_AllocObject (klass, klass->size_in_bytes);
     2922        PUSHA (res);
     2923      }
     2924      NEXT_INSN;
     2925#endif /* DIRECT_THREADED */
     2926
     2927    insn_newarray:
     2928      {
     2929        int atype = GET1U ();
    21872930        int size  = POPI();
    21882931        jobject result = _Jv_NewArray (atype, size);
     
    21912934      NEXT_INSN;
    21922935
    2193      insn_anewarray:
    2194       SAVE_PC;
    2195       {
    2196         int index = get2u (pc); pc += 2;
     2936    insn_anewarray:
     2937      {
     2938        int index = GET2U ();
    21972939        jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
    21982940        int size  = POPI();
     
    22002942        jobject result = _Jv_NewObjectArray (size, klass, 0);
    22012943        PUSHA (result);
    2202       }
    2203       NEXT_INSN;
    2204 
    2205      insn_arraylength:
     2944
     2945#ifdef DIRECT_THREADED
     2946        pc[-2].insn = &&anewarray_resolved;
     2947        pc[-1].datum = klass;
     2948#endif /* DIRECT_THREADED */
     2949      }
     2950      NEXT_INSN;
     2951
     2952#ifdef DIRECT_THREADED
     2953    anewarray_resolved:
     2954      {
     2955        jclass klass = (jclass) AVAL ();
     2956        int size = POPI ();
     2957        jobject result = _Jv_NewObjectArray (size, klass, 0);
     2958        PUSHA (result);
     2959      }
     2960      NEXT_INSN;
     2961#endif /* DIRECT_THREADED */
     2962
     2963    insn_arraylength:
    22062964      {
    22072965        __JArray *arr = (__JArray*)POPA();
     
    22112969      NEXT_INSN;
    22122970
    2213      insn_athrow:
    2214       SAVE_PC;
     2971    insn_athrow:
    22152972      {
    22162973        jobject value = POPA();
     
    22192976      NEXT_INSN;
    22202977
    2221      insn_checkcast:
    2222       SAVE_PC;
     2978    insn_checkcast:
    22232979      {
    22242980        jobject value = POPA();
    2225         jint index = get2u (pc); pc += 2;
     2981        jint index = GET2U ();
    22262982        jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
    22272983
    22282984        if (value != NULL && ! to->isInstance (value))
    2229           {
    2230             throw new java::lang::ClassCastException (to->getName());
    2231           }
     2985          throw new java::lang::ClassCastException (to->getName());
    22322986
    22332987        PUSHA (value);
    2234       }
    2235       NEXT_INSN;
    2236 
    2237      insn_instanceof:
    2238       SAVE_PC;
     2988
     2989#ifdef DIRECT_THREADED
     2990        pc[-2].insn = &&checkcast_resolved;
     2991        pc[-1].datum = to;
     2992#endif /* DIRECT_THREADED */
     2993      }
     2994      NEXT_INSN;
     2995
     2996#ifdef DIRECT_THREADED
     2997    checkcast_resolved:
     2998      {
     2999        jobject value = POPA ();
     3000        jclass to = (jclass) AVAL ();
     3001        if (value != NULL && ! to->isInstance (value))
     3002          throw new java::lang::ClassCastException (to->getName());
     3003        PUSHA (value);
     3004      }
     3005      NEXT_INSN;
     3006#endif /* DIRECT_THREADED */
     3007
     3008    insn_instanceof:
    22393009      {
    22403010        jobject value = POPA();
    2241         jint index = get2u (pc); pc += 2;
     3011        jint index = GET2U ();
    22423012        jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
    22433013        PUSHI (to->isInstance (value));
    2244       }
    2245       NEXT_INSN;
    2246 
    2247      insn_monitorenter:
    2248       SAVE_PC;
     3014
     3015#ifdef DIRECT_THREADED
     3016        pc[-2].insn = &&instanceof_resolved;
     3017        pc[-1].datum = to;
     3018#endif /* DIRECT_THREADED */
     3019      }
     3020      NEXT_INSN;
     3021
     3022#ifdef DIRECT_THREADED
     3023    instanceof_resolved:
     3024      {
     3025        jobject value = POPA ();
     3026        jclass to = (jclass) AVAL ();
     3027        PUSHI (to->isInstance (value));
     3028      }
     3029      NEXT_INSN;
     3030#endif /* DIRECT_THREADED */
     3031
     3032    insn_monitorenter:
    22493033      {
    22503034        jobject value = POPA();
     
    22543038      NEXT_INSN;
    22553039
    2256      insn_monitorexit:
    2257       SAVE_PC;
     3040    insn_monitorexit:
    22583041      {
    22593042        jobject value = POPA();
     
    22633046      NEXT_INSN;
    22643047
    2265      insn_ifnull:
    2266       {
    2267         unsigned char* base_pc = pc-1;
    2268         jint offset = get2s (pc); pc += 2;
     3048    insn_ifnull:
     3049      {
    22693050        jobject val = POPA();
    22703051        if (val == NULL)
    2271           pc = base_pc+offset;
    2272       }
    2273       NEXT_INSN;
    2274 
    2275      insn_ifnonnull:
    2276       {
    2277         unsigned char* base_pc = pc-1;
    2278         jint offset = get2s (pc); pc += 2;
     3052          TAKE_GOTO;
     3053        else
     3054          SKIP_GOTO;
     3055      }
     3056      NEXT_INSN;
     3057
     3058    insn_ifnonnull:
     3059      {
    22793060        jobject val = POPA();
    22803061        if (val != NULL)
    2281           pc = base_pc+offset;
    2282       }
    2283       NEXT_INSN;
    2284 
    2285      insn_wide:
    2286       SAVE_PC;
     3062          TAKE_GOTO;
     3063        else
     3064          SKIP_GOTO;
     3065      }
     3066      NEXT_INSN;
     3067
     3068    insn_multianewarray:
     3069      {
     3070        int kind_index = GET2U ();
     3071        int dim        = GET1U ();
     3072
     3073        jclass type   
     3074          = (_Jv_ResolvePoolEntry (defining_class, kind_index)).clazz;
     3075        _Jv_InitClass (type);
     3076        jint *sizes    = (jint*) __builtin_alloca (sizeof (jint)*dim);
     3077
     3078        for (int i = dim - 1; i >= 0; i--)
     3079          {
     3080            sizes[i] = POPI ();
     3081          }
     3082
     3083        jobject res    = _Jv_NewMultiArray (type,dim, sizes);
     3084
     3085        PUSHA (res);
     3086      }
     3087      NEXT_INSN;
     3088
     3089#ifndef DIRECT_THREADED
     3090    insn_wide:
    22873091      {
    22883092        jint the_mod_op = get1u (pc++);
     
    23443148
    23453149      }
    2346 
    2347      insn_multianewarray:
    2348       SAVE_PC;
    2349       {
    2350         int kind_index = get2u (pc); pc += 2;
    2351         int dim        = get1u (pc); pc += 1;
    2352 
    2353         jclass type   
    2354           = (_Jv_ResolvePoolEntry (defining_class, kind_index)).clazz;
    2355         _Jv_InitClass (type);
    2356         jint *sizes    = (jint*) __builtin_alloca (sizeof (jint)*dim);
    2357 
    2358         for (int i = dim - 1; i >= 0; i--)
    2359           {
    2360             sizes[i] = POPI ();
    2361           }
    2362 
    2363         jobject res    = _Jv_NewMultiArray (type,dim, sizes);
    2364 
    2365         PUSHA (res);
    2366       }
    2367       NEXT_INSN;
    2368 
    2369      insn_goto_w:
    2370       {
    2371         unsigned char* base_pc = pc-1;
    2372         int offset = get4 (pc); pc += 4;
    2373         pc = base_pc+offset;
    2374       }
    2375       NEXT_INSN;
    2376 
    2377      insn_jsr_w:
    2378       {
    2379         unsigned char* base_pc = pc-1;
    2380         int offset = get4 (pc); pc += 4;
    2381         PUSHA((jobject)pc);
    2382         pc = base_pc+offset;
    2383       }
    2384       NEXT_INSN;
     3150#endif /* DIRECT_THREADED */
     3151    }
     3152  catch (java::lang::Throwable *ex)
     3153    {
     3154#ifdef DIRECT_THREADED
     3155      void *logical_pc = (void *) ((insn_slot *) pc - 1);
     3156#else
     3157      int logical_pc = pc - 1 - bytecode ();
     3158#endif
     3159      _Jv_InterpException *exc = exceptions ();
     3160      jclass exc_class = ex->getClass ();
     3161
     3162      for (int i = 0; i < exc_count; i++)
     3163        {
     3164          if (PCVAL (exc[i].start_pc) <= logical_pc
     3165              && logical_pc < PCVAL (exc[i].end_pc))
     3166            {
     3167#ifdef DIRECT_THREADED
     3168              jclass handler = (jclass) exc[i].handler_type.p;
     3169#else
     3170              jclass handler = NULL;
     3171              if (exc[i].handler_type.i != 0)
     3172                handler = (_Jv_ResolvePoolEntry (defining_class,
     3173                                                 exc[i].handler_type.i)).clazz;
     3174#endif /* DIRECT_THREADED */
     3175
     3176              if (handler == NULL || handler->isAssignableFrom (exc_class))
     3177                {
     3178#ifdef DIRECT_THREADED
     3179                  pc = (insn_slot *) exc[i].handler_pc.p;
     3180#else
     3181                  pc = bytecode () + exc[i].handler_pc.i;
     3182#endif /* DIRECT_THREADED */
     3183                  sp = stack;
     3184                  sp++->o = ex; // Push exception.
     3185                  NEXT_INSN;
     3186                }
     3187            }
     3188        }
     3189
     3190      // No handler, so re-throw.
     3191      throw ex;
     3192    }
    23853193}
    23863194
     3195// This function exists so that the stack-tracing code can find the
     3196// boundaries of the interpreter.
     3197void
     3198_Jv_EndOfInterpreter (void)
     3199{
     3200}
    23873201
    23883202static void
Note: See TracChangeset for help on using the changeset viewer.