hotspot/src/share/vm/code/nmethod.hpp
changeset 5702 201c5cde25bb
parent 5547 f4b087cbb361
parent 5686 5435e77aa3df
child 5896 c60924a89622
--- a/hotspot/src/share/vm/code/nmethod.hpp	Tue Jun 01 11:48:33 2010 -0700
+++ b/hotspot/src/share/vm/code/nmethod.hpp	Wed Jun 02 22:45:42 2010 -0700
@@ -105,6 +105,7 @@
 //  [Relocation]
 //  - relocation information
 //  - constant part          (doubles, longs and floats used in nmethod)
+//  - oop table
 //  [Code]
 //  - code body
 //  - exception handler
@@ -161,6 +162,7 @@
 #endif // def HAVE_DTRACE_H
   int _stub_offset;
   int _consts_offset;
+  int _oops_offset;                       // offset to where embedded oop table begins (inside data)
   int _scopes_data_offset;
   int _scopes_pcs_offset;
   int _dependencies_offset;
@@ -347,7 +349,10 @@
   address stub_begin            () const          { return           header_begin() + _stub_offset          ; }
   address stub_end              () const          { return           header_begin() + _consts_offset        ; }
   address consts_begin          () const          { return           header_begin() + _consts_offset        ; }
-  address consts_end            () const          { return           header_begin() + _scopes_data_offset   ; }
+  address consts_end            () const          { return           header_begin() + _oops_offset          ; }
+  oop*    oops_begin            () const          { return (oop*)   (header_begin() + _oops_offset)         ; }
+  oop*    oops_end              () const          { return (oop*)   (header_begin() + _scopes_data_offset)  ; }
+
   address scopes_data_begin     () const          { return           header_begin() + _scopes_data_offset   ; }
   address scopes_data_end       () const          { return           header_begin() + _scopes_pcs_offset    ; }
   PcDesc* scopes_pcs_begin      () const          { return (PcDesc*)(header_begin() + _scopes_pcs_offset   ); }
@@ -359,20 +364,24 @@
   address nul_chk_table_begin   () const          { return           header_begin() + _nul_chk_table_offset ; }
   address nul_chk_table_end     () const          { return           header_begin() + _nmethod_end_offset   ; }
 
-  int code_size         () const                  { return      code_end         () -      code_begin         (); }
-  int stub_size         () const                  { return      stub_end         () -      stub_begin         (); }
-  int consts_size       () const                  { return      consts_end       () -      consts_begin       (); }
-  int scopes_data_size  () const                  { return      scopes_data_end  () -      scopes_data_begin  (); }
-  int scopes_pcs_size   () const                  { return (intptr_t)scopes_pcs_end   () - (intptr_t)scopes_pcs_begin   (); }
-  int dependencies_size () const                  { return      dependencies_end () -      dependencies_begin (); }
-  int handler_table_size() const                  { return      handler_table_end() -      handler_table_begin(); }
-  int nul_chk_table_size() const                  { return      nul_chk_table_end() -      nul_chk_table_begin(); }
+  // Sizes
+  int code_size         () const                  { return            code_end         () -            code_begin         (); }
+  int stub_size         () const                  { return            stub_end         () -            stub_begin         (); }
+  int consts_size       () const                  { return            consts_end       () -            consts_begin       (); }
+  int oops_size         () const                  { return (address)  oops_end         () - (address)  oops_begin         (); }
+  int scopes_data_size  () const                  { return            scopes_data_end  () -            scopes_data_begin  (); }
+  int scopes_pcs_size   () const                  { return (intptr_t) scopes_pcs_end   () - (intptr_t) scopes_pcs_begin   (); }
+  int dependencies_size () const                  { return            dependencies_end () -            dependencies_begin (); }
+  int handler_table_size() const                  { return            handler_table_end() -            handler_table_begin(); }
+  int nul_chk_table_size() const                  { return            nul_chk_table_end() -            nul_chk_table_begin(); }
 
   int total_size        () const;
 
+  // Containment
   bool code_contains         (address addr) const { return code_begin         () <= addr && addr < code_end         (); }
   bool stub_contains         (address addr) const { return stub_begin         () <= addr && addr < stub_end         (); }
   bool consts_contains       (address addr) const { return consts_begin       () <= addr && addr < consts_end       (); }
+  bool oops_contains         (oop*    addr) const { return oops_begin         () <= addr && addr < oops_end         (); }
   bool scopes_data_contains  (address addr) const { return scopes_data_begin  () <= addr && addr < scopes_data_end  (); }
   bool scopes_pcs_contains   (PcDesc* addr) const { return scopes_pcs_begin   () <= addr && addr < scopes_pcs_end   (); }
   bool handler_table_contains(address addr) const { return handler_table_begin() <= addr && addr < handler_table_end(); }
@@ -431,6 +440,29 @@
   int   version() const                           { return flags.version; }
   void  set_version(int v);
 
+  // Support for oops in scopes and relocs:
+  // Note: index 0 is reserved for null.
+  oop   oop_at(int index) const                   { return index == 0 ? (oop) NULL: *oop_addr_at(index); }
+  oop*  oop_addr_at(int index) const {  // for GC
+    // relocation indexes are biased by 1 (because 0 is reserved)
+    assert(index > 0 && index <= oops_size(), "must be a valid non-zero index");
+    return &oops_begin()[index - 1];
+  }
+
+  void copy_oops(GrowableArray<jobject>* oops);
+
+  // Relocation support
+private:
+  void fix_oop_relocations(address begin, address end, bool initialize_immediates);
+  inline void initialize_immediate_oop(oop* dest, jobject handle);
+
+public:
+  void fix_oop_relocations(address begin, address end) { fix_oop_relocations(begin, end, false); }
+  void fix_oop_relocations()                           { fix_oop_relocations(NULL, NULL, false); }
+
+  bool is_at_poll_return(address pc);
+  bool is_at_poll_or_poll_return(address pc);
+
   // Non-perm oop support
   bool  on_scavenge_root_list() const                  { return (_scavenge_root_state & 1) != 0; }
  protected:
@@ -511,8 +543,8 @@
 
   void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map,
                                      OopClosure* f);
-  virtual void oops_do(OopClosure* f) { oops_do(f, false); }
-  void         oops_do(OopClosure* f, bool do_strong_roots_only);
+  void oops_do(OopClosure* f) { oops_do(f, false); }
+  void oops_do(OopClosure* f, bool do_strong_roots_only);
   bool detect_scavenge_root_oops();
   void verify_scavenge_root_oops() PRODUCT_RETURN;