8019519: PPC64 (part 105): C interpreter: implement support for jvmti early return.

Wed, 03 Jul 2013 11:25:06 +0200

author
goetz
date
Wed, 03 Jul 2013 11:25:06 +0200
changeset 6450
bfd9d884693d
parent 6449
48b178ff07b6
child 6451
0014add32e54

8019519: PPC64 (part 105): C interpreter: implement support for jvmti early return.
Reviewed-by: sspitsyn, kvn

src/share/vm/interpreter/bytecodeInterpreter.cpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/bytecodeInterpreter.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed Jul 03 01:41:42 2013 +0200
     1.2 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Wed Jul 03 11:25:06 2013 +0200
     1.3 @@ -35,6 +35,7 @@
     1.4  #include "oops/objArrayKlass.hpp"
     1.5  #include "oops/oop.inline.hpp"
     1.6  #include "prims/jvmtiExport.hpp"
     1.7 +#include "prims/jvmtiThreadState.hpp"
     1.8  #include "runtime/biasedLocking.hpp"
     1.9  #include "runtime/frame.inline.hpp"
    1.10  #include "runtime/handles.inline.hpp"
    1.11 @@ -197,6 +198,10 @@
    1.12                !THREAD->pop_frame_in_process()) {                                 \
    1.13              goto handle_Pop_Frame;                                               \
    1.14            }                                                                      \
    1.15 +          if (THREAD->jvmti_thread_state() &&                                    \
    1.16 +              THREAD->jvmti_thread_state()->is_earlyret_pending()) {             \
    1.17 +            goto handle_Early_Return;                                            \
    1.18 +          }                                                                      \
    1.19            opcode = *pc;                                                          \
    1.20          }                                                                        \
    1.21        }                                                                          \
    1.22 @@ -411,21 +416,25 @@
    1.23          CACHE_LOCALS();
    1.24  
    1.25  // Call the VM don't check for pending exceptions
    1.26 -#define CALL_VM_NOCHECK(func)                                     \
    1.27 -          DECACHE_STATE();                                        \
    1.28 -          SET_LAST_JAVA_FRAME();                                  \
    1.29 -          func;                                                   \
    1.30 -          RESET_LAST_JAVA_FRAME();                                \
    1.31 -          CACHE_STATE();                                          \
    1.32 -          if (THREAD->pop_frame_pending() &&                      \
    1.33 -              !THREAD->pop_frame_in_process()) {                  \
    1.34 -            goto handle_Pop_Frame;                                \
    1.35 -          }
    1.36 +#define CALL_VM_NOCHECK(func)                                      \
    1.37 +        DECACHE_STATE();                                           \
    1.38 +        SET_LAST_JAVA_FRAME();                                     \
    1.39 +        func;                                                      \
    1.40 +        RESET_LAST_JAVA_FRAME();                                   \
    1.41 +        CACHE_STATE();                                             \
    1.42 +        if (THREAD->pop_frame_pending() &&                         \
    1.43 +            !THREAD->pop_frame_in_process()) {                     \
    1.44 +          goto handle_Pop_Frame;                                   \
    1.45 +        }                                                          \
    1.46 +        if (THREAD->jvmti_thread_state() &&                        \
    1.47 +            THREAD->jvmti_thread_state()->is_earlyret_pending()) { \
    1.48 +          goto handle_Early_Return;                                \
    1.49 +        }
    1.50  
    1.51  // Call the VM and check for pending exceptions
    1.52 -#define CALL_VM(func, label) {                                    \
    1.53 -          CALL_VM_NOCHECK(func);                                  \
    1.54 -          if (THREAD->has_pending_exception()) goto label;        \
    1.55 +#define CALL_VM(func, label) {                                     \
    1.56 +          CALL_VM_NOCHECK(func);                                   \
    1.57 +          if (THREAD->has_pending_exception()) goto label;         \
    1.58          }
    1.59  
    1.60  /*
    1.61 @@ -783,7 +792,6 @@
    1.62      case popping_frame: {
    1.63        // returned from a java call to pop the frame, restart the call
    1.64        // clear the message so we don't confuse ourselves later
    1.65 -      ShouldNotReachHere();  // we don't return this.
    1.66        assert(THREAD->pop_frame_in_process(), "wrong frame pop state");
    1.67        istate->set_msg(no_request);
    1.68        THREAD->clr_pop_frame_in_process();
    1.69 @@ -811,6 +819,10 @@
    1.70        if (THREAD->pop_frame_pending() && !THREAD->pop_frame_in_process()) {
    1.71          goto handle_Pop_Frame;
    1.72        }
    1.73 +      if (THREAD->jvmti_thread_state() &&
    1.74 +          THREAD->jvmti_thread_state()->is_earlyret_pending()) {
    1.75 +        goto handle_Early_Return;
    1.76 +      }
    1.77  
    1.78        if (THREAD->has_pending_exception()) goto handle_exception;
    1.79        // Update the pc by the saved amount of the invoke bytecode size
    1.80 @@ -2708,32 +2720,81 @@
    1.81      // No handler in this activation, unwind and try again
    1.82      THREAD->set_pending_exception(except_oop(), NULL, 0);
    1.83      goto handle_return;
    1.84 -  }  /* handle_exception: */
    1.85 -
    1.86 -
    1.87 +  }  // handle_exception:
    1.88  
    1.89    // Return from an interpreter invocation with the result of the interpretation
    1.90    // on the top of the Java Stack (or a pending exception)
    1.91  
    1.92 -handle_Pop_Frame:
    1.93 -
    1.94 -  // We don't really do anything special here except we must be aware
    1.95 -  // that we can get here without ever locking the method (if sync).
    1.96 -  // Also we skip the notification of the exit.
    1.97 -
    1.98 -  istate->set_msg(popping_frame);
    1.99 -  // Clear pending so while the pop is in process
   1.100 -  // we don't start another one if a call_vm is done.
   1.101 -  THREAD->clr_pop_frame_pending();
   1.102 -  // Let interpreter (only) see the we're in the process of popping a frame
   1.103 -  THREAD->set_pop_frame_in_process();
   1.104 -
   1.105 -handle_return:
   1.106 -  {
   1.107 +  handle_Pop_Frame: {
   1.108 +
   1.109 +    // We don't really do anything special here except we must be aware
   1.110 +    // that we can get here without ever locking the method (if sync).
   1.111 +    // Also we skip the notification of the exit.
   1.112 +
   1.113 +    istate->set_msg(popping_frame);
   1.114 +    // Clear pending so while the pop is in process
   1.115 +    // we don't start another one if a call_vm is done.
   1.116 +    THREAD->clr_pop_frame_pending();
   1.117 +    // Let interpreter (only) see the we're in the process of popping a frame
   1.118 +    THREAD->set_pop_frame_in_process();
   1.119 +
   1.120 +    goto handle_return;
   1.121 +
   1.122 +  } // handle_Pop_Frame
   1.123 +
   1.124 +  // ForceEarlyReturn ends a method, and returns to the caller with a return value
   1.125 +  // given by the invoker of the early return.
   1.126 +  handle_Early_Return: {
   1.127 +
   1.128 +    istate->set_msg(early_return);
   1.129 +
   1.130 +    // Clear expression stack.
   1.131 +    topOfStack = istate->stack_base() - Interpreter::stackElementWords;
   1.132 +
   1.133 +    JvmtiThreadState *ts = THREAD->jvmti_thread_state();
   1.134 +
   1.135 +    // Push the value to be returned.
   1.136 +    switch (istate->method()->result_type()) {
   1.137 +      case T_BOOLEAN:
   1.138 +      case T_SHORT:
   1.139 +      case T_BYTE:
   1.140 +      case T_CHAR:
   1.141 +      case T_INT:
   1.142 +        SET_STACK_INT(->earlyret_value().i, 0);
   1.143 +        MORE_STACK(1);
   1.144 +        break;
   1.145 +      case T_LONG:
   1.146 +        SET_STACK_LONG(ts->earlyret_value().j, 1);
   1.147 +        MORE_STACK(2);
   1.148 +        break;
   1.149 +      case T_FLOAT:
   1.150 +        SET_STACK_FLOAT(ts->earlyret_value().f, 0);
   1.151 +        MORE_STACK(1);
   1.152 +        break;
   1.153 +      case T_DOUBLE:
   1.154 +        SET_STACK_DOUBLE(ts->earlyret_value().d, 1);
   1.155 +        MORE_STACK(2);
   1.156 +        break;
   1.157 +      case T_ARRAY:
   1.158 +      case T_OBJECT:
   1.159 +        SET_STACK_OBJECT(ts->earlyret_oop(), 0);
   1.160 +        MORE_STACK(1);
   1.161 +        break;
   1.162 +    }
   1.163 +
   1.164 +    ts->clr_earlyret_value();
   1.165 +    ts->set_earlyret_oop(NULL);
   1.166 +    ts->clr_earlyret_pending();
   1.167 +
   1.168 +    // Fall through to handle_return.
   1.169 +
   1.170 +  } // handle_Early_Return
   1.171 +
   1.172 +  handle_return: {
   1.173      DECACHE_STATE();
   1.174  
   1.175 -    bool suppress_error = istate->msg() == popping_frame;
   1.176 -    bool suppress_exit_event = THREAD->has_pending_exception() || suppress_error;
   1.177 +    bool suppress_error = istate->msg() == popping_frame || istate->msg() == early_return;
   1.178 +    bool suppress_exit_event = THREAD->has_pending_exception() || istate->msg() == popping_frame;
   1.179      Handle original_exception(THREAD, THREAD->pending_exception());
   1.180      Handle illegal_state_oop(THREAD, NULL);
   1.181  
   1.182 @@ -2946,7 +3007,6 @@
   1.183          THREAD->set_pending_exception(illegal_state_oop(), NULL, 0);
   1.184        else
   1.185          THREAD->set_pending_exception(original_exception(), NULL, 0);
   1.186 -      istate->set_return_kind((Bytecodes::Code)opcode);
   1.187        UPDATE_PC_AND_RETURN(0);
   1.188      }
   1.189  
   1.190 @@ -2965,13 +3025,12 @@
   1.191                                  LOCALS_SLOT(METHOD->size_of_parameters() - 1));
   1.192          THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit);
   1.193        }
   1.194 -      THREAD->clr_pop_frame_in_process();
   1.195 +    } else {
   1.196 +      istate->set_msg(return_from_method);
   1.197      }
   1.198  
   1.199      // Normal return
   1.200      // Advance the pc and return to frame manager
   1.201 -    istate->set_msg(return_from_method);
   1.202 -    istate->set_return_kind((Bytecodes::Code)opcode);
   1.203      UPDATE_PC_AND_RETURN(1);
   1.204    } /* handle_return: */
   1.205  
   1.206 @@ -3246,7 +3305,6 @@
   1.207    tty->print_cr("result_to_call._bcp_advance: %d ", this->_result._to_call._bcp_advance);
   1.208    tty->print_cr("osr._osr_buf: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_buf);
   1.209    tty->print_cr("osr._osr_entry: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_entry);
   1.210 -  tty->print_cr("result_return_kind 0x%x ", (int) this->_result._return_kind);
   1.211    tty->print_cr("prev_link: " INTPTR_FORMAT, (uintptr_t) this->_prev_link);
   1.212    tty->print_cr("native_mirror: " INTPTR_FORMAT, (uintptr_t) this->_oop_temp);
   1.213    tty->print_cr("stack_base: " INTPTR_FORMAT, (uintptr_t) this->_stack_base);
     2.1 --- a/src/share/vm/interpreter/bytecodeInterpreter.hpp	Wed Jul 03 01:41:42 2013 +0200
     2.2 +++ b/src/share/vm/interpreter/bytecodeInterpreter.hpp	Wed Jul 03 11:25:06 2013 +0200
     2.3 @@ -66,27 +66,26 @@
     2.4  typedef class BytecodeInterpreter* interpreterState;
     2.5  
     2.6  struct call_message {
     2.7 -    class Method* _callee;    /* method to call during call_method request */
     2.8 -    address   _callee_entry_point;   /* address to jump to for call_method request */
     2.9 -    int       _bcp_advance;          /* size of the invoke bytecode operation */
    2.10 +  class Method* _callee;           // method to call during call_method request
    2.11 +  address _callee_entry_point;     // address to jump to for call_method request
    2.12 +  int _bcp_advance;                // size of the invoke bytecode operation
    2.13  };
    2.14  
    2.15  struct osr_message {
    2.16 -    address _osr_buf;                 /* the osr buffer */
    2.17 -    address _osr_entry;               /* the entry to the osr method */
    2.18 +  address _osr_buf;                 // the osr buffer
    2.19 +  address _osr_entry;               // the entry to the osr method
    2.20  };
    2.21  
    2.22  struct osr_result {
    2.23 -  nmethod* nm;                       /* osr nmethod */
    2.24 -  address return_addr;               /* osr blob return address */
    2.25 +  nmethod* nm;                      // osr nmethod
    2.26 +  address return_addr;              // osr blob return address
    2.27  };
    2.28  
    2.29  // Result returned to frame manager
    2.30  union frame_manager_message {
    2.31 -    call_message _to_call;            /* describes callee */
    2.32 -    Bytecodes::Code _return_kind;     /* i_return, a_return, ... */
    2.33 -    osr_message _osr;                 /* describes the osr */
    2.34 -    osr_result _osr_result;           /* result of OSR request */
    2.35 +  call_message _to_call;            // describes callee
    2.36 +  osr_message _osr;                 // describes the osr
    2.37 +  osr_result _osr_result;           // result of OSR request
    2.38  };
    2.39  
    2.40  class BytecodeInterpreter : StackObj {
    2.41 @@ -115,7 +114,8 @@
    2.42           more_monitors,             // need a new monitor
    2.43           throwing_exception,        // unwind stack and rethrow
    2.44           popping_frame,             // unwind call and retry call
    2.45 -         do_osr                     // request this invocation be OSR's
    2.46 +         do_osr,                    // request this invocation be OSR's
    2.47 +         early_return               // early return as commanded by jvmti
    2.48      };
    2.49  
    2.50  private:
    2.51 @@ -216,8 +216,6 @@
    2.52  inline int bcp_advance() { return _result._to_call._bcp_advance; }
    2.53  inline void set_bcp_advance(int count) { _result._to_call._bcp_advance = count; }
    2.54  
    2.55 -inline void set_return_kind(Bytecodes::Code kind) { _result._return_kind = kind; }
    2.56 -
    2.57  inline interpreterState prev() { return _prev_link; }
    2.58  
    2.59  inline intptr_t* stack() { return _stack; }

mercurial