< prev index next >

src/hotspot/share/runtime/frame.hpp

Print this page
@@ -24,10 +24,12 @@
  
  #ifndef SHARE_RUNTIME_FRAME_HPP
  #define SHARE_RUNTIME_FRAME_HPP
  
  #include "code/vmregTypes.hpp"
+ #include "compiler/oopMap.hpp"
+ #include "oops/stackChunkOop.hpp"
  #include "runtime/basicLock.hpp"
  #include "runtime/monitorChunk.hpp"
  #include "utilities/growableArray.hpp"
  #include "utilities/macros.hpp"
  #ifdef ZERO

@@ -42,10 +44,11 @@
  class vframeArray;
  class JavaCallWrapper;
  class Method;
  class methodHandle;
  class RegisterMap;
+ class InterpreterOopMap;
  
  enum class DerivedPointerIterationMode {
    _with_table,
    _directly,
    _ignore

@@ -58,14 +61,20 @@
  // frames because of inlining.
  
  class frame {
   private:
    // Instance variables:
-   intptr_t* _sp; // stack pointer (from Thread::last_Java_sp)
+   union {
+     intptr_t* _sp; // stack pointer (from Thread::last_Java_sp)
+     struct {
+       int _offset_sp; // used by frames in continuation chunks
+       int _frame_index;
+     };
+   };
    address   _pc; // program counter (the next instruction after the call)
- 
-   CodeBlob* _cb; // CodeBlob that "owns" pc
+   mutable CodeBlob* _cb; // CodeBlob that "owns" pc
+   mutable const ImmutableOopMap* _oop_map; // oop map, for compiled/stubs frames only
    enum deopt_state {
      not_deoptimized,
      is_deoptimized,
      unknown
    };

@@ -74,10 +83,14 @@
  
   public:
    // Constructors
    frame();
  
+   explicit frame(bool dummy) {} // no initialization
+ 
+   explicit frame(intptr_t* sp);
+ 
  #ifndef PRODUCT
    // This is a generic constructor which is only used by pns() in debug.cpp.
    // pns (i.e. print native stack) uses this constructor to create a starting
    // frame for stack walking. The implementation of this constructor is platform
    // dependent (i.e. SPARC doesn't need an 'fp' argument an will ignore it) but

@@ -97,16 +110,33 @@
    // hardware would want to see in the native frame. The only user (at this point)
    // is deoptimization. It likely no one else should ever use it.
    address raw_pc() const;
  
    void set_pc( address   newpc );
+   void set_pc_preserve_deopt( address   newpc );
+   void set_pc_preserve_deopt(address newpc, CodeBlob* cb);
  
    intptr_t* sp() const           { return _sp; }
    void set_sp( intptr_t* newsp ) { _sp = newsp; }
  
+   int offset_sp() const { return _offset_sp; }
+   void set_offset_sp( int newsp ) { _offset_sp = newsp; }
+   int frame_index() const { return _frame_index; }
+   void set_frame_index( int index ) { _frame_index = index; }
+ 
+   static int sender_sp_ret_address_offset();
  
    CodeBlob* cb() const           { return _cb; }
+   inline CodeBlob* get_cb() const;
+   // inline void set_cb(CodeBlob* cb);
+ 
+   const ImmutableOopMap* oop_map() const {
+     if (_oop_map == NULL) {
+       _oop_map = get_oop_map();
+     }
+     return _oop_map;
+   }
  
    // patching operations
    void   patch_pc(Thread* thread, address pc);
  
    // Every frame needs to return a unique id which distinguishes it from all other frames.

@@ -126,10 +156,11 @@
    // Compares for strict equality. Rarely used or needed.
    // It can return a different result than f1.id() == f2.id()
    bool equal(frame other) const;
  
    // type testers
+   bool is_empty()                const { return _pc == NULL; }
    bool is_interpreted_frame()    const;
    bool is_java_frame()           const;
    bool is_entry_frame()          const;             // Java frame called from C?
    bool is_stub_frame()           const;
    bool is_ignored_frame()        const;

@@ -150,12 +181,23 @@
    bool should_be_deoptimized() const;
  
    // tells whether this frame can be deoptimized
    bool can_be_deoptimized() const;
  
-   // returns the frame size in stack slots
-   int frame_size(RegisterMap* map) const;
+   // the frame size in machine words
+   inline int frame_size() const;
+ 
+   // the number of oops in the frame for non-interpreted frames
+   inline int num_oops() const;
+ 
+   // the size, in words, of stack-passed arguments
+   inline int compiled_frame_stack_argsize() const;
+ 
+   inline void interpreted_frame_oop_map(InterpreterOopMap* mask) const;
+ 
+   // the number of oops in the frame
+   inline int interpreted_frame_num_oops(InterpreterOopMap* mask) const;
  
    // returns the sending frame
    frame sender(RegisterMap* map) const;
  
    bool safe_for_sender(JavaThread *thread);

@@ -167,10 +209,11 @@
    // NB: receiver must not be first frame
    frame java_sender() const;
  
   private:
    // Helper methods for better factored code in frame::sender
+   template <bool stub>
    frame sender_for_compiled_frame(RegisterMap* map) const;
    frame sender_for_entry_frame(RegisterMap* map) const;
    frame sender_for_interpreter_frame(RegisterMap* map) const;
    frame sender_for_native_frame(RegisterMap* map) const;
    frame sender_for_optimized_entry_frame(RegisterMap* map) const;

@@ -183,10 +226,14 @@
  
   public:
  
    intptr_t* addr_at(int index) const             { return &fp()[index];    }
    intptr_t  at(int index) const                  { return *addr_at(index); }
+   // in interpreter frames in continuation stacks, internal addresses are relative to fp.
+   intptr_t  at_relative(int index) const         { return (intptr_t)(fp() + fp()[index]); }
+   template <bool relative> 
+   intptr_t at(int index) const                   { return relative ? at_relative(index) : at(index); }
  
    // accessors for locals
    oop obj_at(int offset) const                   { return *obj_at_addr(offset);  }
    void obj_at_put(int offset, oop value)         { *obj_at_addr(offset) = value; }
  

@@ -211,10 +258,14 @@
    void deoptimize(JavaThread* thread);
  
    // The frame's original SP, before any extension by an interpreted callee;
    // used for packing debug info into vframeArray objects and vframeArray lookup.
    intptr_t* unextended_sp() const;
+   void set_unextended_sp(intptr_t* value);
+ 
+   int offset_unextended_sp() const;
+   void set_offset_unextended_sp(int value);
  
    // returns the stack pointer of the calling frame
    intptr_t* sender_sp() const;
  
    // Returns the real 'frame pointer' for the current frame.

@@ -240,10 +291,11 @@
  
   public:
    // Locals
  
    // The _at version returns a pointer because the address is used for GC.
+   template <bool relative = false>
    intptr_t* interpreter_frame_local_at(int index) const;
  
    void interpreter_frame_set_locals(intptr_t* locs);
  
    // byte code index

@@ -266,29 +318,29 @@
    BasicLock* get_native_monitor();
    oop        get_native_receiver();
  
    // Find receiver for an invoke when arguments are just pushed on stack (i.e., callee stack-frame is
    // not setup)
-   oop interpreter_callee_receiver(Symbol* signature)     { return *interpreter_callee_receiver_addr(signature); }
+   oop interpreter_callee_receiver(Symbol* signature);
  
  
    oop* interpreter_callee_receiver_addr(Symbol* signature);
  
  
    // expression stack (may go up or down, direction == 1 or -1)
   public:
-   intptr_t* interpreter_frame_expression_stack() const;
+   template <bool relative = false> intptr_t* interpreter_frame_expression_stack() const;
  
    // The _at version returns a pointer because the address is used for GC.
-   intptr_t* interpreter_frame_expression_stack_at(jint offset) const;
+   template <bool relative = false> intptr_t* interpreter_frame_expression_stack_at(jint offset) const;
  
    // top of expression stack
-   intptr_t* interpreter_frame_tos_at(jint offset) const;
-   intptr_t* interpreter_frame_tos_address() const;
+   template <bool relative = false> intptr_t* interpreter_frame_tos_at(jint offset) const;
+   template <bool relative = false> intptr_t* interpreter_frame_tos_address() const;
  
  
-   jint  interpreter_frame_expression_stack_size() const;
+   template <bool relative = false> jint  interpreter_frame_expression_stack_size() const;
  
    intptr_t* interpreter_frame_sender_sp() const;
  
    // template based interpreter deoptimization support
    void  set_interpreter_frame_sender_sp(intptr_t* sender_sp);

@@ -305,15 +357,18 @@
    //                                 it points to one beyond where the first element will be.
    // interpreter_frame_monitor_size  reports the allocation size of a monitor in the interpreter stack.
    //                                 this value is >= BasicObjectLock::size(), and may be rounded up
  
    BasicObjectLock* interpreter_frame_monitor_begin() const;
+   template <bool relative = false> 
    BasicObjectLock* interpreter_frame_monitor_end()   const;
+   template <bool relative = false>
    BasicObjectLock* next_monitor_in_interpreter_frame(BasicObjectLock* current) const;
    BasicObjectLock* previous_monitor_in_interpreter_frame(BasicObjectLock* current) const;
    static int interpreter_frame_monitor_size();
  
+   template <bool relative = false>
    void interpreter_frame_verify_monitor(BasicObjectLock* value) const;
  
    // Return/result value from this interpreter frame
    // If the method return type is T_OBJECT or T_ARRAY populates oop_result
    // For other (non-T_VOID) the appropriate field in the jvalue is populated

@@ -352,45 +407,65 @@
    // For debugging
   private:
    const char* print_name() const;
  
    void describe_pd(FrameValues& values, int frame_no);
+   void describe_top_pd(FrameValues& values);
  
   public:
    void print_value() const { print_value_on(tty,NULL); }
    void print_value_on(outputStream* st, JavaThread *thread) const;
+   template <bool relative = false>
    void print_on(outputStream* st) const;
+   template <bool relative = false>
    void interpreter_frame_print_on(outputStream* st) const;
    void print_on_error(outputStream* st, char* buf, int buflen, bool verbose = false) const;
    static void print_C_frame(outputStream* st, char* buf, int buflen, address pc);
  
    // Add annotated descriptions of memory locations belonging to this frame to values
-   void describe(FrameValues& values, int frame_no);
+   template <bool relative = false>
+   void describe(FrameValues& values, int frame_no, const RegisterMap* reg_map=NULL);
+   void describe_top(FrameValues& values);
  
    // Conversion from a VMReg to physical stack location
-   address oopmapreg_to_location(VMReg reg, const RegisterMap* reg_map) const;
-   oop* oopmapreg_to_oop_location(VMReg reg, const RegisterMap* reg_map) const;
+   template <typename RegisterMapT>
+   address oopmapreg_to_location(VMReg reg, const RegisterMapT* reg_map) const;
+   template <typename RegisterMapT>
+   oop* oopmapreg_to_oop_location(VMReg reg, const RegisterMapT* reg_map) const;
  
    // Oops-do's
    void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f) const;
+   template <bool relative = false>
    void oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache = true) const;
+   template <bool relative = false>
+   void oops_interpreted_do(OopClosure* f, const RegisterMap* map, const InterpreterOopMap& mask) const;
  
   private:
    void oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) const;
+   template <bool relative = false>
+   void oops_interpreted_do0(OopClosure* f, const RegisterMap* map, methodHandle m, jint bci, const InterpreterOopMap& mask) const;
  
    // Iteration of oops
-   void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map,
-                         bool use_interpreter_oop_map_cache, DerivedPointerIterationMode derived_mode) const;
+   void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, DerivedPointerIterationMode derived_mode, const RegisterMap* map, bool use_interpreter_oop_map_cache) const;
+ 
    void oops_entry_do(OopClosure* f, const RegisterMap* map) const;
-   void oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map,
-                          DerivedPointerIterationMode derived_mode) const;
+   void oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, DerivedPointerIterationMode derived_mode, const RegisterMap* map) const;
    int adjust_offset(Method* method, int index); // helper for above fn
   public:
    // Memory management
-   void oops_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map,
-                DerivedPointerIterationMode derived_mode) const;
-   void oops_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map) const;
+   void oops_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map) {
+ #if COMPILER2_OR_JVMCI
+     DerivedPointerIterationMode dpim = DerivedPointerTable::is_active() ?
+                                        DerivedPointerIterationMode::_with_table :
+                                        DerivedPointerIterationMode::_ignore;
+ #else
+     DerivedPointerIterationMode dpim = DerivedPointerIterationMode::_ignore;;
+ #endif
+     oops_do_internal(f, cf, NULL, dpim, map, true);
+   }
+   void oops_do(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, const RegisterMap* map) { oops_do_internal(f, cf, df, DerivedPointerIterationMode::_ignore, map, true); }
+   void oops_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map, DerivedPointerIterationMode derived_mode) const { oops_do_internal(f, cf, NULL, derived_mode, map, true); }
    void nmethods_do(CodeBlobClosure* cf) const;
  
    // RedefineClasses support for finding live interpreted methods on the stack
    void metadata_do(MetadataClosure* f) const;
  

@@ -436,19 +511,23 @@
        return a->priority - b->priority;
      }
      return a->location - b->location;
    }
  
+   void print_on(outputStream* out, int min_index, int max_index, intptr_t* v0, intptr_t* v1, bool relative = false);
+ 
   public:
    // Used by frame functions to describe locations.
    void describe(int owner, intptr_t* location, const char* description, int priority = 0);
  
  #ifdef ASSERT
    void validate();
  #endif
    void print(JavaThread* thread) { print_on(thread, tty); }
    void print_on(JavaThread* thread, outputStream* out);
+   void print(stackChunkOop chunk) { print_on(chunk, tty); }
+   void print_on(stackChunkOop chunk, outputStream* out);
  };
  
  #endif
  
  
< prev index next >