3239 } |
3239 } |
3240 return NULL; |
3240 return NULL; |
3241 JVM_END |
3241 JVM_END |
3242 |
3242 |
3243 |
3243 |
3244 // Utility object for collecting method holders walking down the stack |
|
3245 class KlassLink: public ResourceObj { |
|
3246 public: |
|
3247 KlassHandle klass; |
|
3248 KlassLink* next; |
|
3249 |
|
3250 KlassLink(KlassHandle k) { klass = k; next = NULL; } |
|
3251 }; |
|
3252 |
|
3253 |
|
3254 JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env)) |
3244 JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env)) |
3255 JVMWrapper("JVM_GetClassContext"); |
3245 JVMWrapper("JVM_GetClassContext"); |
3256 ResourceMark rm(THREAD); |
3246 ResourceMark rm(THREAD); |
3257 JvmtiVMObjectAllocEventCollector oam; |
3247 JvmtiVMObjectAllocEventCollector oam; |
3258 // Collect linked list of (handles to) method holders |
|
3259 KlassLink* first = NULL; |
|
3260 KlassLink* last = NULL; |
|
3261 int depth = 0; |
|
3262 vframeStream vfst(thread); |
3248 vframeStream vfst(thread); |
3263 |
3249 |
3264 if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) { |
3250 if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) { |
3265 // This must only be called from SecurityManager.getClassContext |
3251 // This must only be called from SecurityManager.getClassContext |
3266 Method* m = vfst.method(); |
3252 Method* m = vfst.method(); |
3270 THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext"); |
3256 THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext"); |
3271 } |
3257 } |
3272 } |
3258 } |
3273 |
3259 |
3274 // Collect method holders |
3260 // Collect method holders |
|
3261 GrowableArray<KlassHandle>* klass_array = new GrowableArray<KlassHandle>(); |
3275 for (; !vfst.at_end(); vfst.security_next()) { |
3262 for (; !vfst.at_end(); vfst.security_next()) { |
3276 Method* m = vfst.method(); |
3263 Method* m = vfst.method(); |
3277 // Native frames are not returned |
3264 // Native frames are not returned |
3278 if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) { |
3265 if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) { |
3279 Klass* holder = m->method_holder(); |
3266 Klass* holder = m->method_holder(); |
3280 assert(holder->is_klass(), "just checking"); |
3267 assert(holder->is_klass(), "just checking"); |
3281 depth++; |
3268 klass_array->append(holder); |
3282 KlassLink* l = new KlassLink(KlassHandle(thread, holder)); |
|
3283 if (first == NULL) { |
|
3284 first = last = l; |
|
3285 } else { |
|
3286 last->next = l; |
|
3287 last = l; |
|
3288 } |
|
3289 } |
3269 } |
3290 } |
3270 } |
3291 |
3271 |
3292 // Create result array of type [Ljava/lang/Class; |
3272 // Create result array of type [Ljava/lang/Class; |
3293 objArrayOop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), depth, CHECK_NULL); |
3273 objArrayOop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), klass_array->length(), CHECK_NULL); |
3294 // Fill in mirrors corresponding to method holders |
3274 // Fill in mirrors corresponding to method holders |
3295 int index = 0; |
3275 for (int i = 0; i < klass_array->length(); i++) { |
3296 while (first != NULL) { |
3276 result->obj_at_put(i, klass_array->at(i)->java_mirror()); |
3297 result->obj_at_put(index++, first->klass()->java_mirror()); |
3277 } |
3298 first = first->next; |
|
3299 } |
|
3300 assert(index == depth, "just checking"); |
|
3301 |
3278 |
3302 return (jobjectArray) JNIHandles::make_local(env, result); |
3279 return (jobjectArray) JNIHandles::make_local(env, result); |
3303 JVM_END |
3280 JVM_END |
3304 |
3281 |
3305 |
3282 |