Mercurial > hg > truffle
comparison src/share/vm/prims/jvmtiTagMap.cpp @ 3816:88dce6a60ac8
6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
Summary: Call collect_stack_roots() before collect_simple_roots() as an optimization.
Reviewed-by: ysr, dsamersoff, dcubed
Contributed-by: ashok.srinivasa.murthy@oracle.com
author | dcubed |
---|---|
date | Wed, 29 Jun 2011 20:28:58 -0700 |
parents | d425748f2203 |
children | 2b150750d53d |
comparison
equal
deleted
inserted
replaced
3815:d425748f2203 | 3816:88dce6a60ac8 |
---|---|
3032 } | 3032 } |
3033 return true; | 3033 return true; |
3034 } | 3034 } |
3035 | 3035 |
3036 | 3036 |
3037 // collects all simple (non-stack) roots. | 3037 // Collects all simple (non-stack) roots except for threads; |
3038 // threads are handled in collect_stack_roots() as an optimization. | |
3038 // if there's a heap root callback provided then the callback is | 3039 // if there's a heap root callback provided then the callback is |
3039 // invoked for each simple root. | 3040 // invoked for each simple root. |
3040 // if an object reference callback is provided then all simple | 3041 // if an object reference callback is provided then all simple |
3041 // roots are pushed onto the marking stack so that they can be | 3042 // roots are pushed onto the marking stack so that they can be |
3042 // processed later | 3043 // processed later |
3063 ObjectSynchronizer::oops_do(&blk); | 3064 ObjectSynchronizer::oops_do(&blk); |
3064 if (blk.stopped()) { | 3065 if (blk.stopped()) { |
3065 return false; | 3066 return false; |
3066 } | 3067 } |
3067 | 3068 |
3068 // Threads | 3069 // threads are now handled in collect_stack_roots() |
3069 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) { | |
3070 oop threadObj = thread->threadObj(); | |
3071 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { | |
3072 bool cont = CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD, threadObj); | |
3073 if (!cont) { | |
3074 return false; | |
3075 } | |
3076 } | |
3077 } | |
3078 | 3070 |
3079 // Other kinds of roots maintained by HotSpot | 3071 // Other kinds of roots maintained by HotSpot |
3080 // Many of these won't be visible but others (such as instances of important | 3072 // Many of these won't be visible but others (such as instances of important |
3081 // exceptions) will be visible. | 3073 // exceptions) will be visible. |
3082 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER); | 3074 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER); |
3184 } | 3176 } |
3185 return true; | 3177 return true; |
3186 } | 3178 } |
3187 | 3179 |
3188 | 3180 |
3189 // collects all stack roots - for each thread it walks the execution | 3181 // Collects the simple roots for all threads and collects all |
3182 // stack roots - for each thread it walks the execution | |
3190 // stack to find all references and local JNI refs. | 3183 // stack to find all references and local JNI refs. |
3191 inline bool VM_HeapWalkOperation::collect_stack_roots() { | 3184 inline bool VM_HeapWalkOperation::collect_stack_roots() { |
3192 JNILocalRootsClosure blk; | 3185 JNILocalRootsClosure blk; |
3193 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) { | 3186 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) { |
3194 oop threadObj = thread->threadObj(); | 3187 oop threadObj = thread->threadObj(); |
3195 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { | 3188 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { |
3189 // Collect the simple root for this thread before we | |
3190 // collect its stack roots | |
3191 if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD, | |
3192 threadObj)) { | |
3193 return false; | |
3194 } | |
3196 if (!collect_stack_roots(thread, &blk)) { | 3195 if (!collect_stack_roots(thread, &blk)) { |
3197 return false; | 3196 return false; |
3198 } | 3197 } |
3199 } | 3198 } |
3200 } | 3199 } |
3249 // If either collect_stack_roots() or collect_simple_roots() | 3248 // If either collect_stack_roots() or collect_simple_roots() |
3250 // returns false at this point, then there are no mark bits | 3249 // returns false at this point, then there are no mark bits |
3251 // to reset. | 3250 // to reset. |
3252 ObjectMarker::set_needs_reset(false); | 3251 ObjectMarker::set_needs_reset(false); |
3253 | 3252 |
3253 // Calling collect_stack_roots() before collect_simple_roots() | |
3254 // can result in a big performance boost for an agent that is | |
3255 // focused on analyzing references in the thread stacks. | |
3256 if (!collect_stack_roots()) return; | |
3257 | |
3254 if (!collect_simple_roots()) return; | 3258 if (!collect_simple_roots()) return; |
3255 if (!collect_stack_roots()) return; | |
3256 | 3259 |
3257 // no early return so enable heap traversal to reset the mark bits | 3260 // no early return so enable heap traversal to reset the mark bits |
3258 ObjectMarker::set_needs_reset(true); | 3261 ObjectMarker::set_needs_reset(true); |
3259 } else { | 3262 } else { |
3260 visit_stack()->push(initial_object()()); | 3263 visit_stack()->push(initial_object()()); |