1 /*
   2  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 #include "precompiled.hpp"
  25 #include "gc/z/zBarrier.inline.hpp"
  26 #include "gc/z/zHeap.inline.hpp"
  27 #include "gc/z/zOop.inline.hpp"
  28 #include "gc/z/zOopClosures.inline.hpp"
  29 #include "oops/oop.inline.hpp"
  30 #include "runtime/safepoint.hpp"
  31 #include "utilities/debug.hpp"
  32 
  33 bool ZBarrier::during_mark() {
  34   return ZGlobalPhase == ZPhaseMark;
  35 }
  36 
  37 bool ZBarrier::during_relocate() {
  38   return ZGlobalPhase == ZPhaseRelocate;
  39 }
  40 
  41 template <bool finalizable>
  42 bool ZBarrier::should_mark_through(uintptr_t addr) {
  43   // Finalizable marked oops can still exists on the heap after marking
  44   // has completed, in which case we just want to convert this into a
  45   // good oop and not push it on the mark stack.
  46   if (!during_mark()) {
  47     assert(ZAddress::is_marked(addr), "Should be marked");
  48     assert(ZAddress::is_finalizable(addr), "Should be finalizable");
  49     return false;
  50   }
  51 
  52   // During marking, we mark through already marked oops to avoid having
  53   // some large part of the object graph hidden behind a pushed, but not
  54   // yet flushed, entry on a mutator mark stack. Always marking through
  55   // allows the GC workers to proceed through the object graph even if a
  56   // mutator touched an oop first, which in turn will reduce the risk of
  57   // having to flush mark stacks multiple times to terminate marking.
  58   //
  59   // However, when doing finalizable marking we don't always want to mark
  60   // through. First, marking through an already strongly marked oop would
  61   // be wasteful, since we will then proceed to do finalizable marking on
  62   // an object which is, or will be, marked strongly. Second, marking
  63   // through an already finalizable marked oop would also be wasteful,
  64   // since such oops can never end up on a mutator mark stack and can
  65   // therefore not hide some part of the object graph from GC workers.
  66   if (finalizable) {
  67     return !ZAddress::is_marked(addr);
  68   }
  69 
  70   // Mark through
  71   return true;
  72 }
  73 
  74 template <bool finalizable, bool publish>
  75 uintptr_t ZBarrier::mark(uintptr_t addr) {
  76   uintptr_t good_addr;
  77 
  78   if (ZAddress::is_marked(addr)) {
  79     // Already marked, but try to mark though anyway
  80     good_addr = ZAddress::good(addr);
  81   } else if (ZAddress::is_remapped(addr)) {
  82     // Already remapped, but also needs to be marked
  83     good_addr = ZAddress::good(addr);
  84   } else {
  85     // Needs to be both remapped and marked
  86     good_addr = remap(addr);
  87   }
  88 
  89   // Mark
  90   if (should_mark_through<finalizable>(addr)) {
  91     ZHeap::heap()->mark_object<finalizable, publish>(good_addr);
  92   }
  93 
  94   return good_addr;
  95 }
  96 
  97 uintptr_t ZBarrier::remap(uintptr_t addr) {
  98   assert(!ZAddress::is_good(addr), "Should not be good");
  99   assert(!ZAddress::is_weak_good(addr), "Should not be weak good");
 100 
 101   if (ZHeap::heap()->is_relocating(addr)) {
 102     // Forward
 103     return ZHeap::heap()->forward_object(addr);
 104   }
 105 
 106   // Remap
 107   return ZAddress::good(addr);
 108 }
 109 
 110 uintptr_t ZBarrier::relocate(uintptr_t addr) {
 111   assert(!ZAddress::is_good(addr), "Should not be good");
 112   assert(!ZAddress::is_weak_good(addr), "Should not be weak good");
 113 
 114   if (ZHeap::heap()->is_relocating(addr)) {
 115     // Relocate
 116     return ZHeap::heap()->relocate_object(addr);
 117   }
 118 
 119   // Remap
 120   return ZAddress::good(addr);
 121 }
 122 
 123 uintptr_t ZBarrier::relocate_or_mark(uintptr_t addr) {
 124   return during_relocate() ? relocate(addr) : mark<Strong, Publish>(addr);
 125 }
 126 
 127 uintptr_t ZBarrier::relocate_or_remap(uintptr_t addr) {
 128   return during_relocate() ? relocate(addr) : remap(addr);
 129 }
 130 
 131 //
 132 // Load barrier
 133 //
 134 uintptr_t ZBarrier::load_barrier_on_oop_slow_path(uintptr_t addr) {
 135   return relocate_or_mark(addr);
 136 }
 137 
 138 void ZBarrier::load_barrier_on_oop_fields(oop o) {
 139   assert(ZOop::is_good(o), "Should be good");
 140   ZLoadBarrierOopClosure cl;
 141   o->oop_iterate(&cl);
 142 }
 143 
 144 //
 145 // Weak load barrier
 146 //
 147 uintptr_t ZBarrier::weak_load_barrier_on_oop_slow_path(uintptr_t addr) {
 148   return ZAddress::is_weak_good(addr) ? ZAddress::good(addr) : relocate_or_remap(addr);
 149 }
 150 
 151 uintptr_t ZBarrier::weak_load_barrier_on_weak_oop_slow_path(uintptr_t addr) {
 152   const uintptr_t good_addr = weak_load_barrier_on_oop_slow_path(addr);
 153   if (ZHeap::heap()->is_object_strongly_live(good_addr)) {
 154     return good_addr;
 155   }
 156 
 157   // Not strongly live
 158   return 0;
 159 }
 160 
 161 uintptr_t ZBarrier::weak_load_barrier_on_phantom_oop_slow_path(uintptr_t addr) {
 162   const uintptr_t good_addr = weak_load_barrier_on_oop_slow_path(addr);
 163   if (ZHeap::heap()->is_object_live(good_addr)) {
 164     return good_addr;
 165   }
 166 
 167   // Not live
 168   return 0;
 169 }
 170 
 171 //
 172 // Keep alive barrier
 173 //
 174 uintptr_t ZBarrier::keep_alive_barrier_on_weak_oop_slow_path(uintptr_t addr) {
 175   const uintptr_t good_addr = weak_load_barrier_on_oop_slow_path(addr);
 176   assert(ZHeap::heap()->is_object_strongly_live(good_addr), "Should be live");
 177   return good_addr;
 178 }
 179 
 180 uintptr_t ZBarrier::keep_alive_barrier_on_phantom_oop_slow_path(uintptr_t addr) {
 181   const uintptr_t good_addr = weak_load_barrier_on_oop_slow_path(addr);
 182   assert(ZHeap::heap()->is_object_live(good_addr), "Should be live");
 183   return good_addr;
 184 }
 185 
 186 //
 187 // Mark barrier
 188 //
 189 uintptr_t ZBarrier::mark_barrier_on_oop_slow_path(uintptr_t addr) {
 190   return mark<Strong, Overflow>(addr);
 191 }
 192 
 193 uintptr_t ZBarrier::mark_barrier_on_finalizable_oop_slow_path(uintptr_t addr) {
 194   const uintptr_t good_addr = mark<Finalizable, Overflow>(addr);
 195   if (ZAddress::is_good(addr)) {
 196     // If the oop was already strongly marked/good, then we do
 197     // not want to downgrade it to finalizable marked/good.
 198     return good_addr;
 199   }
 200 
 201   // Make the oop finalizable marked/good, instead of normal marked/good.
 202   // This is needed because an object might first becomes finalizable
 203   // marked by the GC, and then loaded by a mutator thread. In this case,
 204   // the mutator thread must be able to tell that the object needs to be
 205   // strongly marked. The finalizable bit in the oop exists to make sure
 206   // that a load of a finalizable marked oop will fall into the barrier
 207   // slow path so that we can mark the object as strongly reachable.
 208   return ZAddress::finalizable_good(good_addr);
 209 }
 210 
 211 uintptr_t ZBarrier::mark_barrier_on_root_oop_slow_path(uintptr_t addr) {
 212   assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
 213   assert(during_mark(), "Invalid phase");
 214 
 215   // Mark
 216   return mark<Strong, Publish>(addr);
 217 }
 218 
 219 //
 220 // Relocate barrier
 221 //
 222 uintptr_t ZBarrier::relocate_barrier_on_root_oop_slow_path(uintptr_t addr) {
 223   assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
 224   assert(during_relocate(), "Invalid phase");
 225 
 226   // Relocate
 227   return relocate(addr);
 228 }
 229 
 230 //
 231 // Narrow oop variants, never used.
 232 //
 233 oop ZBarrier::load_barrier_on_oop_field(volatile narrowOop* p) {
 234   ShouldNotReachHere();
 235   return NULL;
 236 }
 237 
 238 oop ZBarrier::load_barrier_on_oop_field_preloaded(volatile narrowOop* p, oop o) {
 239   ShouldNotReachHere();
 240   return NULL;
 241 }
 242 
 243 void ZBarrier::load_barrier_on_oop_array(volatile narrowOop* p, size_t length) {
 244   ShouldNotReachHere();
 245 }
 246 
 247 oop ZBarrier::load_barrier_on_weak_oop_field_preloaded(volatile narrowOop* p, oop o) {
 248   ShouldNotReachHere();
 249   return NULL;
 250 }
 251 
 252 oop ZBarrier::load_barrier_on_phantom_oop_field_preloaded(volatile narrowOop* p, oop o) {
 253   ShouldNotReachHere();
 254   return NULL;
 255 }
 256 
 257 oop ZBarrier::weak_load_barrier_on_oop_field_preloaded(volatile narrowOop* p, oop o) {
 258   ShouldNotReachHere();
 259   return NULL;
 260 }
 261 
 262 oop ZBarrier::weak_load_barrier_on_weak_oop_field_preloaded(volatile narrowOop* p, oop o) {
 263   ShouldNotReachHere();
 264   return NULL;
 265 }
 266 
 267 oop ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(volatile narrowOop* p, oop o) {
 268   ShouldNotReachHere();
 269   return NULL;
 270 }