rev 52360 : 8212605: Pure-Java implementation of AccessController.doPrivileged

   1 /*
   2  * Copyright (c) 2014, 2018, 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 
  25 #include "precompiled.hpp"
  26 #include "aot/aotLoader.hpp"
  27 #include "classfile/classLoaderDataGraph.hpp"
  28 #include "classfile/stringTable.hpp"
  29 #include "gc/shared/strongRootsScope.hpp"
  30 #include "jfr/leakprofiler/utilities/unifiedOop.hpp"
  31 #include "jfr/leakprofiler/checkpoint/rootResolver.hpp"
  32 #include "memory/iterator.hpp"
  33 #include "oops/klass.hpp"
  34 #include "oops/markOop.hpp"
  35 #include "oops/oop.hpp"
  36 #include "prims/jvmtiThreadState.hpp"

  37 #include "runtime/frame.inline.hpp"
  38 #include "runtime/mutexLocker.hpp"
  39 #include "runtime/threadSMR.inline.hpp"
  40 #include "runtime/vframe_hp.hpp"
  41 #include "services/management.hpp"
  42 #include "utilities/growableArray.hpp"
  43 
  44 class ReferenceLocateClosure : public OopClosure {
  45  protected:
  46   RootCallback& _callback;
  47   RootCallbackInfo _info;
  48   bool _complete;
  49 
  50   void do_oop_shared(const void* ref);
  51 
  52  public:
  53   ReferenceLocateClosure(RootCallback& callback,
  54                          OldObjectRoot::System system,
  55                          OldObjectRoot::Type type,
  56                          const void* context) : _callback(callback),
  57                                                 _info(),
  58                                                 _complete(false) {
  59     _info._high = NULL;
  60     _info._low = NULL;
  61     _info._system = system;
  62     _info._type = type;
  63     _info._context = context;
  64   }
  65 
  66   virtual void do_oop(oop* ref);
  67   virtual void do_oop(narrowOop* ref);
  68 
  69   bool complete() const {
  70     return _complete;
  71   }
  72 };
  73 
  74 void ReferenceLocateClosure::do_oop_shared(const void* ref) {
  75   assert(ref != NULL, "invariant");
  76   if (!_complete) {
  77     _info._high = ref;
  78     _complete = _callback.process(_info);
  79   }
  80 }
  81 
  82 void ReferenceLocateClosure::do_oop(oop* ref) {
  83   do_oop_shared(ref);
  84 }
  85 
  86 void ReferenceLocateClosure::do_oop(narrowOop* ref) {
  87   do_oop_shared(ref);
  88 }
  89 
  90 class ReferenceToRootClosure : public StackObj {
  91  private:
  92   RootCallback& _callback;
  93   RootCallbackInfo _info;
  94   bool _complete;
  95 
  96   bool do_cldg_roots();
  97   bool do_object_synchronizer_roots();
  98   bool do_universe_roots();
  99   bool do_jni_handle_roots();
 100   bool do_jvmti_roots();
 101   bool do_system_dictionary_roots();
 102   bool do_management_roots();
 103   bool do_string_table_roots();
 104   bool do_aot_loader_roots();
 105 
 106   bool do_roots();
 107 
 108  public:
 109   ReferenceToRootClosure(RootCallback& callback) : _callback(callback),
 110                                                    _info(),
 111                                                    _complete(false) {
 112     _info._high = NULL;
 113     _info._low = NULL;
 114     _info._context = NULL;
 115     _info._system = OldObjectRoot::_system_undetermined;
 116     _info._type = OldObjectRoot::_type_undetermined;
 117 
 118     assert_locked_or_safepoint(Threads_lock);
 119     do_roots();
 120   }
 121 
 122   bool complete() const {
 123     return _complete;
 124   }
 125 };
 126 
 127 bool ReferenceToRootClosure::do_cldg_roots() {
 128   assert(!complete(), "invariant");
 129   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_class_loader_data, OldObjectRoot::_type_undetermined, NULL);
 130   CLDToOopClosure cldt_closure(&rlc, ClassLoaderData::_claim_strong);
 131   ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure);
 132   return rlc.complete();
 133 }
 134 
 135 bool ReferenceToRootClosure::do_object_synchronizer_roots() {
 136   assert(!complete(), "invariant");
 137   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_object_synchronizer, OldObjectRoot::_type_undetermined, NULL);
 138   ObjectSynchronizer::oops_do(&rlc);
 139   return rlc.complete();
 140 }
 141 
 142 bool ReferenceToRootClosure::do_universe_roots() {
 143   assert(!complete(), "invariant");
 144   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_universe, OldObjectRoot::_type_undetermined, NULL);
 145   Universe::oops_do(&rlc);
 146   return rlc.complete();
 147 }
 148 
 149 bool ReferenceToRootClosure::do_jni_handle_roots() {
 150   assert(!complete(), "invariant");
 151   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_global_jni_handles, OldObjectRoot::_global_jni_handle, NULL);
 152   JNIHandles::oops_do(&rlc);
 153   return rlc.complete();
 154 }
 155 
 156 bool ReferenceToRootClosure::do_jvmti_roots() {
 157   assert(!complete(), "invariant");
 158   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_jvmti, OldObjectRoot::_global_jni_handle, NULL);
 159   JvmtiExport::oops_do(&rlc);
 160   return rlc.complete();
 161 }
 162 
 163 bool ReferenceToRootClosure::do_system_dictionary_roots() {
 164   assert(!complete(), "invariant");
 165   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_system_dictionary, OldObjectRoot::_type_undetermined, NULL);
 166   SystemDictionary::oops_do(&rlc);
 167   return rlc.complete();
 168 }
 169 
 170 bool ReferenceToRootClosure::do_management_roots() {
 171   assert(!complete(), "invariant");
 172   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_management, OldObjectRoot::_type_undetermined, NULL);
 173   Management::oops_do(&rlc);
 174   return rlc.complete();
 175 }
 176 
 177 bool ReferenceToRootClosure::do_string_table_roots() {
 178   assert(!complete(), "invariant");
 179   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_string_table, OldObjectRoot::_type_undetermined, NULL);
 180   StringTable::oops_do(&rlc);
 181   return rlc.complete();
 182 }
 183 
 184 bool ReferenceToRootClosure::do_aot_loader_roots() {
 185   assert(!complete(), "invariant");
 186   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_aot, OldObjectRoot::_type_undetermined, NULL);
 187   AOTLoader::oops_do(&rcl);
 188   return rcl.complete();
 189 }
 190 
 191 bool ReferenceToRootClosure::do_roots() {
 192   assert(!complete(), "invariant");
 193   assert(OldObjectRoot::_system_undetermined == _info._system, "invariant");
 194   assert(OldObjectRoot::_type_undetermined == _info._type, "invariant");
 195 
 196   if (do_cldg_roots()) {
 197     _complete = true;
 198     return true;
 199   }
 200 
 201   if (do_object_synchronizer_roots()) {
 202    _complete = true;
 203     return true;
 204   }
 205 
 206   if (do_universe_roots()) {
 207    _complete = true;
 208     return true;
 209   }
 210 
 211   if (do_jni_handle_roots()) {
 212    _complete = true;
 213     return true;
 214   }
 215 
 216   if (do_jvmti_roots()) {
 217    _complete = true;
 218     return true;
 219   }
 220 
 221   if (do_system_dictionary_roots()) {
 222    _complete = true;
 223     return true;
 224   }
 225 
 226   if (do_management_roots()) {
 227    _complete = true;
 228     return true;
 229   }
 230 
 231   if (do_string_table_roots()) {
 232    _complete = true;
 233     return true;
 234   }
 235 
 236   if (do_aot_loader_roots()) {
 237    _complete = true;
 238     return true;
 239   }
 240 
 241   return false;
 242 }
 243 
 244 class ReferenceToThreadRootClosure : public StackObj {
 245  private:
 246   RootCallback& _callback;
 247   bool _complete;
 248 
 249   bool do_java_threads_oops(JavaThread* jt);
 250   bool do_thread_roots(JavaThread* jt);
 251   bool do_thread_stack_fast(JavaThread* jt);
 252   bool do_thread_stack_detailed(JavaThread* jt);
 253   bool do_thread_jni_handles(JavaThread* jt);
 254   bool do_thread_handle_area(JavaThread* jt);
 255 
 256  public:
 257   ReferenceToThreadRootClosure(RootCallback& callback) :_callback(callback), _complete(false) {
 258     assert_locked_or_safepoint(Threads_lock);
 259     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
 260       if (do_thread_roots(jt)) {
 261         return;
 262       }
 263     }
 264   }
 265 
 266   bool complete() const {
 267     return _complete;
 268   }
 269 };
 270 
 271 bool ReferenceToThreadRootClosure::do_thread_handle_area(JavaThread* jt) {
 272   assert(jt != NULL, "invariant");
 273   assert(!complete(), "invariant");
 274   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_handle_area, jt);
 275   jt->handle_area()->oops_do(&rcl);
 276   return rcl.complete();
 277 }
 278 
 279 bool ReferenceToThreadRootClosure::do_thread_jni_handles(JavaThread* jt) {
 280   assert(jt != NULL, "invariant");
 281   assert(!complete(), "invariant");
 282 
 283   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_local_jni_handle, jt);
 284   jt->active_handles()->oops_do(&rcl);
 285   return rcl.complete();
 286 }
 287 
 288 bool ReferenceToThreadRootClosure::do_thread_stack_fast(JavaThread* jt) {
 289   assert(jt != NULL, "invariant");
 290   assert(!complete(), "invariant");
 291 
 292   if (_callback.entries() == 0) {
 293     _complete = true;
 294     return true;
 295   }
 296 
 297   RootCallbackInfo info;
 298   info._high = NULL;
 299   info._low = NULL;
 300   info._context = jt;
 301   info._system = OldObjectRoot::_threads;
 302   info._type = OldObjectRoot::_stack_variable;
 303 
 304   for (int i = 0; i < _callback.entries(); ++i) {
 305     const address adr = (address)_callback.at(i);
 306     if (jt->is_in_usable_stack(adr)) {
 307       info._high = adr;
 308       _complete = _callback.process(info);
 309       if (_complete) {
 310         return true;
 311       }
 312     }
 313   }
 314   assert(!complete(), "invariant");
 315   return false;
 316 }
 317 
 318 bool ReferenceToThreadRootClosure::do_thread_stack_detailed(JavaThread* jt) {
 319   assert(jt != NULL, "invariant");
 320   assert(!complete(), "invariant");
 321 
 322   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_stack_variable, jt);
 323 
 324   if (jt->has_last_Java_frame()) {








 325     // traverse the registered growable array gc_array
 326     // can't do this as it is not reachable from outside
 327 
 328     // Traverse the monitor chunks
 329     MonitorChunk* chunk = jt->monitor_chunks();
 330     for (; chunk != NULL; chunk = chunk->next()) {
 331       chunk->oops_do(&rcl);
 332     }
 333 
 334     if (rcl.complete()) {
 335       return true;
 336     }
 337 
 338     // Traverse the execution stack
 339     for (StackFrameStream fst(jt); !fst.is_done(); fst.next()) {
 340       fst.current()->oops_do(&rcl, NULL, fst.register_map());
 341     }
 342 
 343   } // last java frame
 344 
 345   if (rcl.complete()) {
 346     return true;
 347   }
 348 
 349   GrowableArray<jvmtiDeferredLocalVariableSet*>* const list = jt->deferred_locals();
 350   if (list != NULL) {
 351     for (int i = 0; i < list->length(); i++) {
 352       list->at(i)->oops_do(&rcl);
 353     }
 354   }
 355 
 356   if (rcl.complete()) {
 357     return true;
 358   }
 359 
 360   // Traverse instance variables at the end since the GC may be moving things
 361   // around using this function
 362   /*
 363   * // can't reach these oop* from the outside
 364   f->do_oop((oop*) &_threadObj);
 365   f->do_oop((oop*) &_vm_result);
 366   f->do_oop((oop*) &_exception_oop);
 367   f->do_oop((oop*) &_pending_async_exception);
 368   */
 369 
 370   JvmtiThreadState* const jvmti_thread_state = jt->jvmti_thread_state();
 371   if (jvmti_thread_state != NULL) {
 372     jvmti_thread_state->oops_do(&rcl);
 373   }
 374 
 375   return rcl.complete();
 376 }
 377 
 378 bool ReferenceToThreadRootClosure::do_java_threads_oops(JavaThread* jt) {
 379   assert(jt != NULL, "invariant");
 380   assert(!complete(), "invariant");
 381 
 382   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_global_jni_handle, jt);
 383   jt->oops_do(&rcl, NULL);
 384   return rcl.complete();
 385 }
 386 
 387 bool ReferenceToThreadRootClosure::do_thread_roots(JavaThread* jt) {
 388   assert(jt != NULL, "invariant");
 389 
 390   if (do_thread_stack_fast(jt)) {
 391     _complete = true;
 392     return true;
 393   }
 394 
 395   if (do_thread_jni_handles(jt)) {
 396     _complete = true;
 397     return true;
 398   }
 399 
 400   if (do_thread_handle_area(jt)) {
 401     _complete = true;
 402     return true;
 403   }
 404 
 405   if (do_thread_stack_detailed(jt)) {
 406     _complete = true;
 407     return true;
 408   }
 409 
 410   return false;
 411 }
 412 
 413 class RootResolverMarkScope : public MarkScope {
 414 };
 415 
 416 void RootResolver::resolve(RootCallback& callback) {
 417 
 418   // Need to clear cld claim bit before starting
 419   ClassLoaderDataGraph::clear_claimed_marks();
 420   RootResolverMarkScope mark_scope;
 421 
 422   // thread local roots
 423   ReferenceToThreadRootClosure rtrc(callback);
 424   if (rtrc.complete()) {
 425     return;
 426   }
 427   // system global roots
 428   ReferenceToRootClosure rrc(callback);
 429 }
--- EOF ---