< prev index next >

src/hotspot/share/prims/whitebox.cpp

Print this page
*** 47,23 ***
--- 47,26 ---
  #include "gc/shared/genCollectedHeap.hpp"
  #include "jvmtifiles/jvmtiEnv.hpp"
  #include "logging/log.hpp"
  #include "memory/iterator.hpp"
  #include "memory/metadataFactory.hpp"
+ #include "memory/iterator.inline.hpp"
  #include "memory/metaspace/testHelpers.hpp"
  #include "memory/metaspaceUtils.hpp"
  #include "memory/oopFactory.hpp"
  #include "memory/resourceArea.hpp"
  #include "memory/universe.hpp"
  #include "oops/array.hpp"
  #include "oops/compressedOops.hpp"
+ #include "oops/compressedOops.inline.hpp"
  #include "oops/constantPool.inline.hpp"
  #include "oops/klass.inline.hpp"
  #include "oops/method.inline.hpp"
  #include "oops/objArrayKlass.hpp"
  #include "oops/objArrayOop.inline.hpp"
  #include "oops/oop.inline.hpp"
+ #include "oops/objArrayOop.inline.hpp"
  #include "oops/typeArrayOop.inline.hpp"
  #include "prims/resolvedMethodTable.hpp"
  #include "prims/wbtestmethods/parserTests.hpp"
  #include "prims/whitebox.inline.hpp"
  #include "runtime/arguments.hpp"

*** 1830,10 ***
--- 1833,97 ---
  
  WB_ENTRY(jint, WB_ConstantPoolEncodeIndyIndex(JNIEnv* env, jobject wb, jint index))
    return ConstantPool::encode_invokedynamic_index(index);
  WB_END
  
+ WB_ENTRY(jobjectArray, WB_getObjectsViaKlassOopMaps(JNIEnv* env, jobject wb, jobject thing))
+   oop aoop = JNIHandles::resolve(thing);
+   if (!aoop->is_instance()) {
+     return NULL;
+   }
+   instanceHandle ih(THREAD, (instanceOop) aoop);
+   InstanceKlass* klass = InstanceKlass::cast(ih->klass());
+   if (klass->nonstatic_oop_map_count() == 0) {
+     return NULL;
+   }
+   const OopMapBlock* map = klass->start_of_nonstatic_oop_maps();
+   const OopMapBlock* const end = map + klass->nonstatic_oop_map_count();
+   int oop_count = 0;
+   while (map < end) {
+     oop_count += map->count();
+     map++;
+   }
+ 
+   objArrayHandle result_array =
+       oopFactory::new_objArray_handle(vmClasses::Object_klass(), oop_count, CHECK_NULL);
+   map = klass->start_of_nonstatic_oop_maps();
+   int index = 0;
+   while (map < end) {
+     int offset = map->offset();
+     for (unsigned int j = 0; j < map->count(); j++) {
+       result_array->obj_at_put(index++, ih->obj_field(offset));
+       offset += heapOopSize;
+     }
+     map++;
+   }
+   return (jobjectArray)JNIHandles::make_local(THREAD, result_array());
+ WB_END
+ 
+ class CollectOops : public BasicOopIterateClosure {
+  public:
+   GrowableArray<Handle>* array;
+ 
+   jobjectArray create_jni_result(JNIEnv* env, TRAPS) {
+     objArrayHandle result_array =
+         oopFactory::new_objArray_handle(vmClasses::Object_klass(), array->length(), CHECK_NULL);
+     for (int i = 0 ; i < array->length(); i++) {
+       result_array->obj_at_put(i, array->at(i)());
+     }
+     return (jobjectArray)JNIHandles::make_local(THREAD, result_array());
+   }
+ 
+   void add_oop(oop o) {
+     Handle oh = Handle(Thread::current(), o);
+     // Value might be oop, but JLS can't see as Object, just iterate through it...
+     if (oh != NULL && oh->is_inline_type()) {
+       oh->oop_iterate(this);
+     } else {
+       array->append(oh);
+     }
+   }
+ 
+   void do_oop(oop* o) { add_oop(HeapAccess<>::oop_load(o)); }
+   void do_oop(narrowOop* v) { add_oop(HeapAccess<>::oop_load(v)); }
+ };
+ 
+ 
+ WB_ENTRY(jobjectArray, WB_getObjectsViaOopIterator(JNIEnv* env, jobject wb, jobject thing))
+   ResourceMark rm(thread);
+   Handle objh(thread, JNIHandles::resolve(thing));
+   GrowableArray<Handle>* array = new GrowableArray<Handle>(128);
+   CollectOops collectOops;
+   collectOops.array = array;
+   objh->oop_iterate(&collectOops);
+   return collectOops.create_jni_result(env, THREAD);
+ WB_END
+ 
+ WB_ENTRY(jobjectArray, WB_getObjectsViaFrameOopIterator(JNIEnv* env, jobject wb, jint depth))
+   ResourceMark rm(THREAD);
+   GrowableArray<Handle>* array = new GrowableArray<Handle>(128);
+   CollectOops collectOops;
+   collectOops.array = array;
+   StackFrameStream sfs(thread, false /* update */, true /* process_frames */);
+   while (depth > 0) { // Skip the native WB API frame
+     sfs.next();
+     frame* f = sfs.current();
+     f->oops_do(&collectOops, NULL, sfs.register_map());
+     depth--;
+   }
+   return collectOops.create_jni_result(env, THREAD);
+ WB_END
+ 
+ 
  WB_ENTRY(void, WB_ClearInlineCaches(JNIEnv* env, jobject wb, jboolean preserve_static_stubs))
    VM_ClearICs clear_ics(preserve_static_stubs == JNI_TRUE);
    VMThread::execute(&clear_ics);
  WB_END
  

*** 2617,10 ***
--- 2707,16 ---
    {CC"getConstantPoolCacheLength0", CC"(Ljava/lang/Class;)I",  (void*)&WB_GetConstantPoolCacheLength},
    {CC"remapInstructionOperandFromCPCache0",
        CC"(Ljava/lang/Class;I)I",                      (void*)&WB_ConstantPoolRemapInstructionOperandFromCache},
    {CC"encodeConstantPoolIndyIndex0",
        CC"(I)I",                      (void*)&WB_ConstantPoolEncodeIndyIndex},
+   {CC"getObjectsViaKlassOopMaps0",
+       CC"(Ljava/lang/Object;)[Ljava/lang/Object;",    (void*)&WB_getObjectsViaKlassOopMaps},
+   {CC"getObjectsViaOopIterator0",
+           CC"(Ljava/lang/Object;)[Ljava/lang/Object;",(void*)&WB_getObjectsViaOopIterator},
+   {CC"getObjectsViaFrameOopIterator",
+       CC"(I)[Ljava/lang/Object;",                     (void*)&WB_getObjectsViaFrameOopIterator},
    {CC"getMethodBooleanOption",
        CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Boolean;",
                                                        (void*)&WB_GetMethodBooleaneOption},
    {CC"getMethodIntxOption",
        CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Long;",
< prev index next >