< prev index next >

src/hotspot/share/gc/parallel/psClosure.inline.hpp

8211447_01: revision due to comments from StefanJ and Thomas

14  * You should have received a copy of the GNU General Public License version                                               
15  * 2 along with this work; if not, write to the Free Software Foundation,                                                  
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.                                                           
17  *                                                                                                                         
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA                                                 
19  * or visit www.oracle.com if you need additional information or have any                                                  
20  * questions.                                                                                                              
21  *                                                                                                                         
22  */                                                                                                                        
23 
24 #ifndef SHARE_VM_GC_PARALLEL_PSCLOSURE_INLINE_HPP                                                                          
25 #define SHARE_VM_GC_PARALLEL_PSCLOSURE_INLINE_HPP                                                                          
26 
27 #include "gc/parallel/psPromotionManager.inline.hpp"                                                                       
28 #include "gc/parallel/psScavenge.inline.hpp"                                                                               
29 #include "memory/iterator.hpp"                                                                                             
30 #include "oops/access.inline.hpp"                                                                                          
31 #include "oops/oop.inline.hpp"                                                                                             
32 #include "utilities/globalDefinitions.hpp"                                                                                 
33 
34 template<bool promote_immediately>                                                                                         
35 class PSRootsClosure: public OopClosure {                                                                                  
36  private:                                                                                                                  
37   PSPromotionManager* _promotion_manager;                                                                                  
38 
39  protected:                                                                                                                
40   template <class T> void do_oop_work(T *p) {                                                                              
41     if (PSScavenge::should_scavenge(p)) {                                                                                  
42       // We never card mark roots, maybe call a func without test?                                                         
43       _promotion_manager->copy_and_push_safe_barrier<T, promote_immediately>(p);                                           
44     }                                                                                                                      
45   }                                                                                                                        
46  public:                                                                                                                   
47   PSRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }                                                      
48   void do_oop(oop* p)       { PSRootsClosure::do_oop_work(p); }                                                            
49   void do_oop(narrowOop* p) { PSRootsClosure::do_oop_work(p); }                                                            
50 };                                                                                                                         
51 
52 typedef PSRootsClosure</*promote_immediately=*/false> PSScavengeRootsClosure;                                              
53 typedef PSRootsClosure</*promote_immediately=*/true> PSPromoteRootsClosure;                                                
54 
55 // Scavenges a single oop in a ClassLoaderData.                                                                            
56 class PSScavengeFromCLDClosure: public OopClosure {                                                                        
57  private:                                                                                                                  
58   PSPromotionManager* _pm;                                                                                                 
59   // Used to redirty a scanned cld if it has oops                                                                          
60   // pointing to the young generation after being scanned.                                                                 
61   ClassLoaderData*    _scanned_cld;                                                                                        
62  public:                                                                                                                   
63   PSScavengeFromCLDClosure(PSPromotionManager* pm) : _pm(pm), _scanned_cld(NULL) { }                                       
64   void do_oop(narrowOop* p) { ShouldNotReachHere(); }                                                                      
65   void do_oop(oop* p)       {                                                                                              
66     ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();                                                              
67     assert(!psh->is_in_reserved(p), "GC barrier needed");                                                                  
68     if (PSScavenge::should_scavenge(p)) {                                                                                  
69       assert(PSScavenge::should_scavenge(p, true), "revisiting object?");                                                  
70 
71       oop o = *p;                                                                                                          
72       oop new_obj;                                                                                                         
73       if (o->is_forwarded()) {                                                                                             
74         new_obj = o->forwardee();                                                                                          
75       } else {                                                                                                             
76         new_obj = _pm->copy_to_survivor_space</*promote_immediately=*/false>(o);                                           
77       }                                                                                                                    
78       RawAccess<IS_NOT_NULL>::oop_store(p, new_obj);                                                                       
79 
80       if (PSScavenge::is_obj_in_young(new_obj)) {                                                                          
81         do_cld_barrier();                                                                                                  
82       }                                                                                                                    
83     }                                                                                                                      
84   }                                                                                                                        
85 
86   void set_scanned_cld(ClassLoaderData* cld) {                                                                             
87     assert(_scanned_cld == NULL || cld == NULL, "Should always only handling one cld at a time");                          
88     _scanned_cld = cld;                                                                                                    
89   }                                                                                                                        
90 
91  private:                                                                                                                  
92   void do_cld_barrier() {                                                                                                  
93     assert(_scanned_cld != NULL, "Should not be called without having a scanned cld");                                     
94     _scanned_cld->record_modified_oops();                                                                                  
95   }                                                                                                                        
96 };                                                                                                                         
97 
98 // Scavenges the oop in a ClassLoaderData.                                                                                 
99 class PSScavengeCLDClosure: public CLDClosure {                                                                            
100  private:                                                                                                                  
101   PSScavengeFromCLDClosure _oop_closure;                                                                                   
102  protected:                                                                                                                
103  public:                                                                                                                   
104   PSScavengeCLDClosure(PSPromotionManager* pm) : _oop_closure(pm) { }                                                      
105   void do_cld(ClassLoaderData* cld) {                                                                                      
106     // If the cld has not been dirtied we know that there's                                                                
107     // no references into  the young gen and we can skip it.                                                               
108 
109     if (cld->has_modified_oops()) {                                                                                        
110       // Setup the promotion manager to redirty this cld                                                                   
111       // if references are left in the young gen.                                                                          
112       _oop_closure.set_scanned_cld(cld);                                                                                   
113 
114       // Clean the cld since we're going to scavenge all the metadata.                                                     
115       cld->oops_do(&_oop_closure, false, /*clear_modified_oops*/true);                                                     
116 
117       _oop_closure.set_scanned_cld(NULL);                                                                                  
118     }                                                                                                                      
119   }                                                                                                                        
120 };                                                                                                                         
121 
122 #endif                                                                                                                     

14  * You should have received a copy of the GNU General Public License version
15  * 2 along with this work; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19  * or visit www.oracle.com if you need additional information or have any
20  * questions.
21  *
22  */
23 
24 #ifndef SHARE_VM_GC_PARALLEL_PSCLOSURE_INLINE_HPP
25 #define SHARE_VM_GC_PARALLEL_PSCLOSURE_INLINE_HPP
26 
27 #include "gc/parallel/psPromotionManager.inline.hpp"
28 #include "gc/parallel/psScavenge.inline.hpp"
29 #include "memory/iterator.hpp"
30 #include "oops/access.inline.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "utilities/globalDefinitions.hpp"
33 
34 template <bool promote_immediately>
35 class PSRootsClosure: public OopClosure {
36 private:
37   PSPromotionManager* _promotion_manager;
38 

39   template <class T> void do_oop_work(T *p) {
40     if (PSScavenge::should_scavenge(p)) {
41       // We never card mark roots, maybe call a func without test?
42       _promotion_manager->copy_and_push_safe_barrier<T, promote_immediately>(p);
43     }
44   }
45  public:
46   PSRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
47   void do_oop(oop* p)       { PSRootsClosure::do_oop_work(p); }
48   void do_oop(narrowOop* p) { PSRootsClosure::do_oop_work(p); }
49 };
50 
51 typedef PSRootsClosure</*promote_immediately=*/false> PSScavengeRootsClosure;
52 typedef PSRootsClosure</*promote_immediately=*/true> PSPromoteRootsClosure;
53 
54 // Scavenges a single oop in a ClassLoaderData.
55 class PSScavengeFromCLDClosure: public OopClosure {
56 private:
57   PSPromotionManager* _pm;
58   // Used to redirty a scanned cld if it has oops
59   // pointing to the young generation after being scanned.
60   ClassLoaderData*    _scanned_cld;
61 public:
62   PSScavengeFromCLDClosure(PSPromotionManager* pm) : _pm(pm), _scanned_cld(NULL) { }
63   void do_oop(narrowOop* p) { ShouldNotReachHere(); }
64   void do_oop(oop* p)       {
65     ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();
66     assert(!psh->is_in_reserved(p), "GC barrier needed");
67     if (PSScavenge::should_scavenge(p)) {
68       assert(PSScavenge::should_scavenge(p, true), "revisiting object?");
69 
70       oop o = *p;
71       oop new_obj;
72       if (o->is_forwarded()) {
73         new_obj = o->forwardee();
74       } else {
75         new_obj = _pm->copy_to_survivor_space</*promote_immediately=*/false>(o);
76       }
77       RawAccess<IS_NOT_NULL>::oop_store(p, new_obj);
78 
79       if (PSScavenge::is_obj_in_young(new_obj)) {
80         do_cld_barrier();
81       }
82     }
83   }
84 
85   void set_scanned_cld(ClassLoaderData* cld) {
86     assert(_scanned_cld == NULL || cld == NULL, "Should always only handling one cld at a time");
87     _scanned_cld = cld;
88   }
89 
90 private:
91   void do_cld_barrier() {
92     assert(_scanned_cld != NULL, "Should not be called without having a scanned cld");
93     _scanned_cld->record_modified_oops();
94   }
95 };
96 
97 // Scavenges the oop in a ClassLoaderData.
98 class PSScavengeCLDClosure: public CLDClosure {
99 private:
100   PSScavengeFromCLDClosure _oop_closure;
101 public:

102   PSScavengeCLDClosure(PSPromotionManager* pm) : _oop_closure(pm) { }
103   void do_cld(ClassLoaderData* cld) {
104     // If the cld has not been dirtied we know that there's
105     // no references into  the young gen and we can skip it.
106 
107     if (cld->has_modified_oops()) {
108       // Setup the promotion manager to redirty this cld
109       // if references are left in the young gen.
110       _oop_closure.set_scanned_cld(cld);
111 
112       // Clean the cld since we're going to scavenge all the metadata.
113       cld->oops_do(&_oop_closure, false, /*clear_modified_oops*/true);
114 
115       _oop_closure.set_scanned_cld(NULL);
116     }
117   }
118 };
119 
120 #endif
< prev index next >