< prev index next >

src/hotspot/share/runtime/frame.hpp

Print this page

        

@@ -35,10 +35,11 @@
 #endif
 
 typedef class BytecodeInterpreter* interpreterState;
 
 class CodeBlob;
+class CodeBlobLookup;
 class FrameValues;
 class vframeArray;
 class JavaCallWrapper;
 
 

@@ -49,14 +50,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 _sp;
+      int _ref_sp;
+    } _cont_sp;
+  };
   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
   };

@@ -88,16 +95,30 @@
   // 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 cont_sp()     const { return _cont_sp._sp; }
+  int cont_ref_sp() const { return _cont_sp._ref_sp; }
+  int cont_unextended_sp() const;
 
   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.

@@ -117,10 +138,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;

@@ -146,10 +168,13 @@
   int frame_size(RegisterMap* map) const;
 
   // returns the sending frame
   frame sender(RegisterMap* map) const;
 
+  template<typename LOOKUP> // LOOKUP is CodeCache or ContinuationCodeBlobLookup (requires: static CodeBlob* find_blob(address pc))
+  frame frame_sender(RegisterMap* map) const;
+
   bool safe_for_sender(JavaThread *thread);
 
   // returns the sender, but skips conversion frames
   frame real_sender(RegisterMap* map) const;
 

@@ -157,10 +182,11 @@
   // NB: receiver must not be first frame
   frame java_sender() const;
 
  private:
   // Helper methods for better factored code in frame::sender
+  template <typename LOOKUP, 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;
 

@@ -353,30 +379,34 @@
   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);
+  void describe(FrameValues& values, int frame_no, const RegisterMap* reg_map=NULL);
 
   // Conversion from a VMReg to physical stack location
-  oop* oopmapreg_to_location(VMReg reg, const RegisterMap* reg_map) const;
+  template <typename RegisterMapT>
+  oop* oopmapreg_to_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);
   void oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache = true);
+  void oops_interpreted_do(OopClosure* f, const RegisterMap* map, const InterpreterOopMap& mask);
 
  private:
   void oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f);
+  void oops_interpreted_do0(OopClosure* f, const RegisterMap* map, methodHandle m, jint bci, const InterpreterOopMap& mask);
 
   // Iteration of oops
-  void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache);
+  void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, const RegisterMap* map, bool use_interpreter_oop_map_cache);
   void oops_entry_do(OopClosure* f, const RegisterMap* map);
-  void oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map);
+  void oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, const RegisterMap* map);
   int adjust_offset(Method* method, int index); // helper for above fn
  public:
   // Memory management
-  void oops_do(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map) { oops_do_internal(f, cf, map, true); }
+  void oops_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map) { oops_do_internal(f, cf, NULL, map, true); }
+  void oops_do(OopClosure* f, CodeBlobClosure* cf, DerivedOopClosure* df, const RegisterMap* map) { oops_do_internal(f, cf, df, map, true); }
   void nmethods_do(CodeBlobClosure* cf);
 
   // RedefineClasses support for finding live interpreted methods on the stack
   void metadata_do(MetadataClosure* f);
 

@@ -454,11 +484,11 @@
  private:
   frame       _fr;
   RegisterMap _reg_map;
   bool        _is_done;
  public:
-   StackFrameStream(JavaThread *thread, bool update = true);
+   StackFrameStream(JavaThread *thread, bool update = true, bool allow_missing_reg = false);
 
   // Iteration
   inline bool is_done();
   void next()                     { if (!_is_done) _fr = _fr.sender(&_reg_map); }
 
< prev index next >