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 "prims/privilegedStack.hpp"
  38 #include "runtime/frame.inline.hpp"
  39 #include "runtime/mutexLocker.hpp"
  40 #include "runtime/threadSMR.inline.hpp"
  41 #include "runtime/vframe_hp.hpp"
  42 #include "services/management.hpp"
  43 #include "utilities/growableArray.hpp"
  44 
  45 class ReferenceLocateClosure : public OopClosure {
  46  protected:
  47   RootCallback& _callback;
  48   RootCallbackInfo _info;
  49   bool _complete;
  50 
  51   void do_oop_shared(const void* ref);
  52 
  53  public:
  54   ReferenceLocateClosure(RootCallback& callback,
  55                          OldObjectRoot::System system,
  56                          OldObjectRoot::Type type,
  57                          const void* context) : _callback(callback),
  58                                                 _info(),
  59                                                 _complete(false) {
  60     _info._high = NULL;
  61     _info._low = NULL;
  62     _info._system = system;
  63     _info._type = type;
  64     _info._context = context;
  65   }
  66 
  67   virtual void do_oop(oop* ref);
  68   virtual void do_oop(narrowOop* ref);
  69 
  70   bool complete() const {
  71     return _complete;
  72   }
  73 };
  74 
  75 void ReferenceLocateClosure::do_oop_shared(const void* ref) {
  76   assert(ref != NULL, "invariant");
  77   if (!_complete) {
  78     _info._high = ref;
  79     _complete = _callback.process(_info);
  80   }
  81 }
  82 
  83 void ReferenceLocateClosure::do_oop(oop* ref) {
  84   do_oop_shared(ref);
  85 }
  86 
  87 void ReferenceLocateClosure::do_oop(narrowOop* ref) {
  88   do_oop_shared(ref);
  89 }
  90 
  91 class ReferenceToRootClosure : public StackObj {
  92  private:
  93   RootCallback& _callback;
  94   RootCallbackInfo _info;
  95   bool _complete;
  96 
  97   bool do_cldg_roots();
  98   bool do_object_synchronizer_roots();
  99   bool do_universe_roots();
 100   bool do_jni_handle_roots();
 101   bool do_jvmti_roots();
 102   bool do_system_dictionary_roots();
 103   bool do_management_roots();
 104   bool do_string_table_roots();
 105   bool do_aot_loader_roots();
 106 
 107   bool do_roots();
 108 
 109  public:
 110   ReferenceToRootClosure(RootCallback& callback) : _callback(callback),
 111                                                    _info(),
 112                                                    _complete(false) {
 113     _info._high = NULL;
 114     _info._low = NULL;
 115     _info._context = NULL;
 116     _info._system = OldObjectRoot::_system_undetermined;
 117     _info._type = OldObjectRoot::_type_undetermined;
 118 
 119     assert_locked_or_safepoint(Threads_lock);
 120     do_roots();
 121   }
 122 
 123   bool complete() const {
 124     return _complete;
 125   }
 126 };
 127 
 128 bool ReferenceToRootClosure::do_cldg_roots() {
 129   assert(!complete(), "invariant");
 130   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_class_loader_data, OldObjectRoot::_type_undetermined, NULL);
 131   CLDToOopClosure cldt_closure(&rlc, ClassLoaderData::_claim_strong);
 132   ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure);
 133   return rlc.complete();
 134 }
 135 
 136 bool ReferenceToRootClosure::do_object_synchronizer_roots() {
 137   assert(!complete(), "invariant");
 138   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_object_synchronizer, OldObjectRoot::_type_undetermined, NULL);
 139   ObjectSynchronizer::oops_do(&rlc);
 140   return rlc.complete();
 141 }
 142 
 143 bool ReferenceToRootClosure::do_universe_roots() {
 144   assert(!complete(), "invariant");
 145   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_universe, OldObjectRoot::_type_undetermined, NULL);
 146   Universe::oops_do(&rlc);
 147   return rlc.complete();
 148 }
 149 
 150 bool ReferenceToRootClosure::do_jni_handle_roots() {
 151   assert(!complete(), "invariant");
 152   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_global_jni_handles, OldObjectRoot::_global_jni_handle, NULL);
 153   JNIHandles::oops_do(&rlc);
 154   return rlc.complete();
 155 }
 156 
 157 bool ReferenceToRootClosure::do_jvmti_roots() {
 158   assert(!complete(), "invariant");
 159   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_jvmti, OldObjectRoot::_global_jni_handle, NULL);
 160   JvmtiExport::oops_do(&rlc);
 161   return rlc.complete();
 162 }
 163 
 164 bool ReferenceToRootClosure::do_system_dictionary_roots() {
 165   assert(!complete(), "invariant");
 166   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_system_dictionary, OldObjectRoot::_type_undetermined, NULL);
 167   SystemDictionary::oops_do(&rlc);
 168   return rlc.complete();
 169 }
 170 
 171 bool ReferenceToRootClosure::do_management_roots() {
 172   assert(!complete(), "invariant");
 173   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_management, OldObjectRoot::_type_undetermined, NULL);
 174   Management::oops_do(&rlc);
 175   return rlc.complete();
 176 }
 177 
 178 bool ReferenceToRootClosure::do_string_table_roots() {
 179   assert(!complete(), "invariant");
 180   ReferenceLocateClosure rlc(_callback, OldObjectRoot::_string_table, OldObjectRoot::_type_undetermined, NULL);
 181   StringTable::oops_do(&rlc);
 182   return rlc.complete();
 183 }
 184 
 185 bool ReferenceToRootClosure::do_aot_loader_roots() {
 186   assert(!complete(), "invariant");
 187   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_aot, OldObjectRoot::_type_undetermined, NULL);
 188   AOTLoader::oops_do(&rcl);
 189   return rcl.complete();
 190 }
 191 
 192 bool ReferenceToRootClosure::do_roots() {
 193   assert(!complete(), "invariant");
 194   assert(OldObjectRoot::_system_undetermined == _info._system, "invariant");
 195   assert(OldObjectRoot::_type_undetermined == _info._type, "invariant");
 196 
 197   if (do_cldg_roots()) {
 198     _complete = true;
 199     return true;
 200   }
 201 
 202   if (do_object_synchronizer_roots()) {
 203    _complete = true;
 204     return true;
 205   }
 206 
 207   if (do_universe_roots()) {
 208    _complete = true;
 209     return true;
 210   }
 211 
 212   if (do_jni_handle_roots()) {
 213    _complete = true;
 214     return true;
 215   }
 216 
 217   if (do_jvmti_roots()) {
 218    _complete = true;
 219     return true;
 220   }
 221 
 222   if (do_system_dictionary_roots()) {
 223    _complete = true;
 224     return true;
 225   }
 226 
 227   if (do_management_roots()) {
 228    _complete = true;
 229     return true;
 230   }
 231 
 232   if (do_string_table_roots()) {
 233    _complete = true;
 234     return true;
 235   }
 236 
 237   if (do_aot_loader_roots()) {
 238    _complete = true;
 239     return true;
 240   }
 241 
 242   return false;
 243 }
 244 
 245 class ReferenceToThreadRootClosure : public StackObj {
 246  private:
 247   RootCallback& _callback;
 248   bool _complete;
 249 
 250   bool do_java_threads_oops(JavaThread* jt);
 251   bool do_thread_roots(JavaThread* jt);
 252   bool do_thread_stack_fast(JavaThread* jt);
 253   bool do_thread_stack_detailed(JavaThread* jt);
 254   bool do_thread_jni_handles(JavaThread* jt);
 255   bool do_thread_handle_area(JavaThread* jt);
 256 
 257  public:
 258   ReferenceToThreadRootClosure(RootCallback& callback) :_callback(callback), _complete(false) {
 259     assert_locked_or_safepoint(Threads_lock);
 260     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
 261       if (do_thread_roots(jt)) {
 262         return;
 263       }
 264     }
 265   }
 266 
 267   bool complete() const {
 268     return _complete;
 269   }
 270 };
 271 
 272 bool ReferenceToThreadRootClosure::do_thread_handle_area(JavaThread* jt) {
 273   assert(jt != NULL, "invariant");
 274   assert(!complete(), "invariant");
 275   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_handle_area, jt);
 276   jt->handle_area()->oops_do(&rcl);
 277   return rcl.complete();
 278 }
 279 
 280 bool ReferenceToThreadRootClosure::do_thread_jni_handles(JavaThread* jt) {
 281   assert(jt != NULL, "invariant");
 282   assert(!complete(), "invariant");
 283 
 284   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_local_jni_handle, jt);
 285   jt->active_handles()->oops_do(&rcl);
 286   return rcl.complete();
 287 }
 288 
 289 bool ReferenceToThreadRootClosure::do_thread_stack_fast(JavaThread* jt) {
 290   assert(jt != NULL, "invariant");
 291   assert(!complete(), "invariant");
 292 
 293   if (_callback.entries() == 0) {
 294     _complete = true;
 295     return true;
 296   }
 297 
 298   RootCallbackInfo info;
 299   info._high = NULL;
 300   info._low = NULL;
 301   info._context = jt;
 302   info._system = OldObjectRoot::_threads;
 303   info._type = OldObjectRoot::_stack_variable;
 304 
 305   for (int i = 0; i < _callback.entries(); ++i) {
 306     const address adr = (address)_callback.at(i);
 307     if (jt->is_in_usable_stack(adr)) {
 308       info._high = adr;
 309       _complete = _callback.process(info);
 310       if (_complete) {
 311         return true;
 312       }
 313     }
 314   }
 315   assert(!complete(), "invariant");
 316   return false;
 317 }
 318 
 319 bool ReferenceToThreadRootClosure::do_thread_stack_detailed(JavaThread* jt) {
 320   assert(jt != NULL, "invariant");
 321   assert(!complete(), "invariant");
 322 
 323   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_stack_variable, jt);
 324 
 325   if (jt->has_last_Java_frame()) {
 326     PrivilegedElement* const pelem = jt->privileged_stack_top();
 327     if (pelem != NULL) {
 328       pelem->oops_do(&rcl);
 329       if (rcl.complete()) {
 330         return true;
 331       }
 332     }
 333 
 334     // traverse the registered growable array gc_array
 335     // can't do this as it is not reachable from outside
 336 
 337     // Traverse the monitor chunks
 338     MonitorChunk* chunk = jt->monitor_chunks();
 339     for (; chunk != NULL; chunk = chunk->next()) {
 340       chunk->oops_do(&rcl);
 341     }
 342 
 343     if (rcl.complete()) {
 344       return true;
 345     }
 346 
 347     // Traverse the execution stack
 348     for (StackFrameStream fst(jt); !fst.is_done(); fst.next()) {
 349       fst.current()->oops_do(&rcl, NULL, fst.register_map());
 350     }
 351 
 352   } // last java frame
 353 
 354   if (rcl.complete()) {
 355     return true;
 356   }
 357 
 358   GrowableArray<jvmtiDeferredLocalVariableSet*>* const list = jt->deferred_locals();
 359   if (list != NULL) {
 360     for (int i = 0; i < list->length(); i++) {
 361       list->at(i)->oops_do(&rcl);
 362     }
 363   }
 364 
 365   if (rcl.complete()) {
 366     return true;
 367   }
 368 
 369   // Traverse instance variables at the end since the GC may be moving things
 370   // around using this function
 371   /*
 372   * // can't reach these oop* from the outside
 373   f->do_oop((oop*) &_threadObj);
 374   f->do_oop((oop*) &_vm_result);
 375   f->do_oop((oop*) &_exception_oop);
 376   f->do_oop((oop*) &_pending_async_exception);
 377   */
 378 
 379   JvmtiThreadState* const jvmti_thread_state = jt->jvmti_thread_state();
 380   if (jvmti_thread_state != NULL) {
 381     jvmti_thread_state->oops_do(&rcl);
 382   }
 383 
 384   return rcl.complete();
 385 }
 386 
 387 bool ReferenceToThreadRootClosure::do_java_threads_oops(JavaThread* jt) {
 388   assert(jt != NULL, "invariant");
 389   assert(!complete(), "invariant");
 390 
 391   ReferenceLocateClosure rcl(_callback, OldObjectRoot::_threads, OldObjectRoot::_global_jni_handle, jt);
 392   jt->oops_do(&rcl, NULL);
 393   return rcl.complete();
 394 }
 395 
 396 bool ReferenceToThreadRootClosure::do_thread_roots(JavaThread* jt) {
 397   assert(jt != NULL, "invariant");
 398 
 399   if (do_thread_stack_fast(jt)) {
 400     _complete = true;
 401     return true;
 402   }
 403 
 404   if (do_thread_jni_handles(jt)) {
 405     _complete = true;
 406     return true;
 407   }
 408 
 409   if (do_thread_handle_area(jt)) {
 410     _complete = true;
 411     return true;
 412   }
 413 
 414   if (do_thread_stack_detailed(jt)) {
 415     _complete = true;
 416     return true;
 417   }
 418 
 419   return false;
 420 }
 421 
 422 class RootResolverMarkScope : public MarkScope {
 423 };
 424 
 425 void RootResolver::resolve(RootCallback& callback) {
 426 
 427   // Need to clear cld claim bit before starting
 428   ClassLoaderDataGraph::clear_claimed_marks();
 429   RootResolverMarkScope mark_scope;
 430 
 431   // thread local roots
 432   ReferenceToThreadRootClosure rtrc(callback);
 433   if (rtrc.complete()) {
 434     return;
 435   }
 436   // system global roots
 437   ReferenceToRootClosure rrc(callback);
 438 }
--- EOF ---