37 |
37 |
38 static GrowableArray<Handle>* _preserved_oop_stack = NULL; |
38 static GrowableArray<Handle>* _preserved_oop_stack = NULL; |
39 static GrowableArray<markOop>* _preserved_mark_stack = NULL; |
39 static GrowableArray<markOop>* _preserved_mark_stack = NULL; |
40 |
40 |
41 static void enable_biased_locking(Klass* k) { |
41 static void enable_biased_locking(Klass* k) { |
42 Klass::cast(k)->set_prototype_header(markOopDesc::biased_locking_prototype()); |
42 k->set_prototype_header(markOopDesc::biased_locking_prototype()); |
43 } |
43 } |
44 |
44 |
45 class VM_EnableBiasedLocking: public VM_Operation { |
45 class VM_EnableBiasedLocking: public VM_Operation { |
46 private: |
46 private: |
47 bool _is_cheap_allocated; |
47 bool _is_cheap_allocated; |
147 markOop mark = obj->mark(); |
147 markOop mark = obj->mark(); |
148 if (!mark->has_bias_pattern()) { |
148 if (!mark->has_bias_pattern()) { |
149 if (TraceBiasedLocking) { |
149 if (TraceBiasedLocking) { |
150 ResourceMark rm; |
150 ResourceMark rm; |
151 tty->print_cr(" (Skipping revocation of object of type %s because it's no longer biased)", |
151 tty->print_cr(" (Skipping revocation of object of type %s because it's no longer biased)", |
152 Klass::cast(obj->klass())->external_name()); |
152 obj->klass()->external_name()); |
153 } |
153 } |
154 return BiasedLocking::NOT_BIASED; |
154 return BiasedLocking::NOT_BIASED; |
155 } |
155 } |
156 |
156 |
157 uint age = mark->age(); |
157 uint age = mark->age(); |
159 markOop unbiased_prototype = markOopDesc::prototype()->set_age(age); |
159 markOop unbiased_prototype = markOopDesc::prototype()->set_age(age); |
160 |
160 |
161 if (TraceBiasedLocking && (Verbose || !is_bulk)) { |
161 if (TraceBiasedLocking && (Verbose || !is_bulk)) { |
162 ResourceMark rm; |
162 ResourceMark rm; |
163 tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT, |
163 tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT, |
164 (intptr_t) obj, (intptr_t) mark, Klass::cast(obj->klass())->external_name(), (intptr_t) Klass::cast(obj->klass())->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread); |
164 (intptr_t) obj, (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread); |
165 } |
165 } |
166 |
166 |
167 JavaThread* biased_thread = mark->biased_locker(); |
167 JavaThread* biased_thread = mark->biased_locker(); |
168 if (biased_thread == NULL) { |
168 if (biased_thread == NULL) { |
169 // Object is anonymously biased. We can get here if, for |
169 // Object is anonymously biased. We can get here if, for |
324 |
324 |
325 if (TraceBiasedLocking) { |
325 if (TraceBiasedLocking) { |
326 tty->print_cr("* Beginning bulk revocation (kind == %s) because of object " |
326 tty->print_cr("* Beginning bulk revocation (kind == %s) because of object " |
327 INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", |
327 INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", |
328 (bulk_rebias ? "rebias" : "revoke"), |
328 (bulk_rebias ? "rebias" : "revoke"), |
329 (intptr_t) o, (intptr_t) o->mark(), Klass::cast(o->klass())->external_name()); |
329 (intptr_t) o, (intptr_t) o->mark(), o->klass()->external_name()); |
330 } |
330 } |
331 |
331 |
332 jlong cur_time = os::javaTimeMillis(); |
332 jlong cur_time = os::javaTimeMillis(); |
333 o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time); |
333 o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time); |
334 |
334 |
335 |
335 |
336 Klass* k_o = o->klass(); |
336 Klass* k_o = o->klass(); |
337 Klass* klass = Klass::cast(k_o); |
337 Klass* klass = k_o; |
338 |
338 |
339 if (bulk_rebias) { |
339 if (bulk_rebias) { |
340 // Use the epoch in the klass of the object to implicitly revoke |
340 // Use the epoch in the klass of the object to implicitly revoke |
341 // all biases of objects of this data type and force them to be |
341 // all biases of objects of this data type and force them to be |
342 // reacquired. However, we also need to walk the stacks of all |
342 // reacquired. However, we also need to walk the stacks of all |
544 markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark); |
544 markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark); |
545 if (res_mark == biased_value) { |
545 if (res_mark == biased_value) { |
546 return BIAS_REVOKED; |
546 return BIAS_REVOKED; |
547 } |
547 } |
548 } else if (mark->has_bias_pattern()) { |
548 } else if (mark->has_bias_pattern()) { |
549 Klass* k = Klass::cast(obj->klass()); |
549 Klass* k = obj->klass(); |
550 markOop prototype_header = k->prototype_header(); |
550 markOop prototype_header = k->prototype_header(); |
551 if (!prototype_header->has_bias_pattern()) { |
551 if (!prototype_header->has_bias_pattern()) { |
552 // This object has a stale bias from before the bulk revocation |
552 // This object has a stale bias from before the bulk revocation |
553 // for this data type occurred. It's pointless to update the |
553 // for this data type occurred. It's pointless to update the |
554 // heuristics at this point so simply update the header with a |
554 // heuristics at this point so simply update the header with a |
588 |
588 |
589 HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias); |
589 HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias); |
590 if (heuristics == HR_NOT_BIASED) { |
590 if (heuristics == HR_NOT_BIASED) { |
591 return NOT_BIASED; |
591 return NOT_BIASED; |
592 } else if (heuristics == HR_SINGLE_REVOKE) { |
592 } else if (heuristics == HR_SINGLE_REVOKE) { |
593 Klass *k = Klass::cast(obj->klass()); |
593 Klass *k = obj->klass(); |
594 markOop prototype_header = k->prototype_header(); |
594 markOop prototype_header = k->prototype_header(); |
595 if (mark->biased_locker() == THREAD && |
595 if (mark->biased_locker() == THREAD && |
596 prototype_header->bias_epoch() == mark->bias_epoch()) { |
596 prototype_header->bias_epoch() == mark->bias_epoch()) { |
597 // A thread is trying to revoke the bias of an object biased |
597 // A thread is trying to revoke the bias of an object biased |
598 // toward it, again likely due to an identity hash code |
598 // toward it, again likely due to an identity hash code |