42 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, const CodeBlobLayout& layout, |
42 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, const CodeBlobLayout& layout, |
43 int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, |
43 int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, |
44 bool caller_must_gc_arguments) |
44 bool caller_must_gc_arguments) |
45 : CodeBlob(name, type, layout, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments), |
45 : CodeBlob(name, type, layout, frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments), |
46 _mark_for_deoptimization_status(not_marked), |
46 _mark_for_deoptimization_status(not_marked), |
47 _is_unloading_state(0), |
|
48 _method(method) |
47 _method(method) |
49 { |
48 { |
50 init_defaults(); |
49 init_defaults(); |
51 clear_unloading_state(); |
|
52 } |
50 } |
53 |
51 |
54 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, int size, |
52 CompiledMethod::CompiledMethod(Method* method, const char* name, CompilerType type, int size, |
55 int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size, |
53 int header_size, CodeBuffer* cb, int frame_complete_offset, int frame_size, |
56 OopMapSet* oop_maps, bool caller_must_gc_arguments) |
54 OopMapSet* oop_maps, bool caller_must_gc_arguments) |
57 : CodeBlob(name, type, CodeBlobLayout((address) this, size, header_size, cb), cb, |
55 : CodeBlob(name, type, CodeBlobLayout((address) this, size, header_size, cb), cb, |
58 frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments), |
56 frame_complete_offset, frame_size, oop_maps, caller_must_gc_arguments), |
59 _mark_for_deoptimization_status(not_marked), |
57 _mark_for_deoptimization_status(not_marked), |
60 _is_unloading_state(0), |
|
61 _method(method) |
58 _method(method) |
62 { |
59 { |
63 init_defaults(); |
60 init_defaults(); |
64 clear_unloading_state(); |
|
65 } |
61 } |
66 |
62 |
67 void CompiledMethod::init_defaults() { |
63 void CompiledMethod::init_defaults() { |
68 _has_unsafe_access = 0; |
64 _has_unsafe_access = 0; |
69 _has_method_handle_invokes = 0; |
65 _has_method_handle_invokes = 0; |
544 |
540 |
545 // Check that the metadata embedded in the nmethod is alive |
541 // Check that the metadata embedded in the nmethod is alive |
546 DEBUG_ONLY(metadata_do(check_class)); |
542 DEBUG_ONLY(metadata_do(check_class)); |
547 } |
543 } |
548 |
544 |
549 // The _is_unloading_state encodes a tuple comprising the unloading cycle |
|
550 // and the result of IsUnloadingBehaviour::is_unloading() fpr that cycle. |
|
551 // This is the bit layout of the _is_unloading_state byte: 00000CCU |
|
552 // CC refers to the cycle, which has 2 bits, and U refers to the result of |
|
553 // IsUnloadingBehaviour::is_unloading() for that unloading cycle. |
|
554 |
|
555 class IsUnloadingState: public AllStatic { |
|
556 static const uint8_t _is_unloading_mask = 1; |
|
557 static const uint8_t _is_unloading_shift = 0; |
|
558 static const uint8_t _unloading_cycle_mask = 6; |
|
559 static const uint8_t _unloading_cycle_shift = 1; |
|
560 |
|
561 static uint8_t set_is_unloading(uint8_t state, bool value) { |
|
562 state &= ~_is_unloading_mask; |
|
563 if (value) { |
|
564 state |= 1 << _is_unloading_shift; |
|
565 } |
|
566 assert(is_unloading(state) == value, "unexpected unloading cycle overflow"); |
|
567 return state; |
|
568 } |
|
569 |
|
570 static uint8_t set_unloading_cycle(uint8_t state, uint8_t value) { |
|
571 state &= ~_unloading_cycle_mask; |
|
572 state |= value << _unloading_cycle_shift; |
|
573 assert(unloading_cycle(state) == value, "unexpected unloading cycle overflow"); |
|
574 return state; |
|
575 } |
|
576 |
|
577 public: |
|
578 static bool is_unloading(uint8_t state) { return (state & _is_unloading_mask) >> _is_unloading_shift == 1; } |
|
579 static uint8_t unloading_cycle(uint8_t state) { return (state & _unloading_cycle_mask) >> _unloading_cycle_shift; } |
|
580 |
|
581 static uint8_t create(bool is_unloading, uint8_t unloading_cycle) { |
|
582 uint8_t state = 0; |
|
583 state = set_is_unloading(state, is_unloading); |
|
584 state = set_unloading_cycle(state, unloading_cycle); |
|
585 return state; |
|
586 } |
|
587 }; |
|
588 |
|
589 bool CompiledMethod::is_unloading() { |
|
590 uint8_t state = RawAccess<MO_RELAXED>::load(&_is_unloading_state); |
|
591 bool state_is_unloading = IsUnloadingState::is_unloading(state); |
|
592 uint8_t state_unloading_cycle = IsUnloadingState::unloading_cycle(state); |
|
593 if (state_is_unloading) { |
|
594 return true; |
|
595 } |
|
596 if (state_unloading_cycle == CodeCache::unloading_cycle()) { |
|
597 return false; |
|
598 } |
|
599 |
|
600 // The IsUnloadingBehaviour is responsible for checking if there are any dead |
|
601 // oops in the CompiledMethod, by calling oops_do on it. |
|
602 state_unloading_cycle = CodeCache::unloading_cycle(); |
|
603 state_is_unloading = IsUnloadingBehaviour::current()->is_unloading(this); |
|
604 |
|
605 state = IsUnloadingState::create(state_is_unloading, state_unloading_cycle); |
|
606 |
|
607 RawAccess<MO_RELAXED>::store(&_is_unloading_state, state); |
|
608 |
|
609 return state_is_unloading; |
|
610 } |
|
611 |
|
612 void CompiledMethod::clear_unloading_state() { |
|
613 uint8_t state = IsUnloadingState::create(false, CodeCache::unloading_cycle()); |
|
614 RawAccess<MO_RELAXED>::store(&_is_unloading_state, state); |
|
615 } |
|
616 |
|
617 // Called to clean up after class unloading for live nmethods and from the sweeper |
545 // Called to clean up after class unloading for live nmethods and from the sweeper |
618 // for all methods. |
546 // for all methods. |
619 void CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) { |
547 void CompiledMethod::cleanup_inline_caches_impl(bool unloading_occurred, bool clean_all) { |
620 assert(CompiledICLocker::is_safe(this), "mt unsafe call"); |
548 assert(CompiledICLocker::is_safe(this), "mt unsafe call"); |
621 ResourceMark rm; |
549 ResourceMark rm; |