1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_RUNTIME_STACKWATERMARK_HPP 26 #define SHARE_RUNTIME_STACKWATERMARK_HPP 27 28 #include "memory/allocation.hpp" 29 #include "runtime/mutex.hpp" 30 #include "runtime/stackWatermarkKind.hpp" 31 32 class frame; 33 class JavaThread; 34 class RegisterMap; 35 class StackWatermarkFramesIterator; 36 37 // The StackWatermark state is a tuple comprising the last epoch in which 38 // the watermark has been processed, and a boolean denoting whether the whole 39 // processing of the lazy snapshot has been processed or not. It is written 40 // in a way that can be used outside of locks, so that fast path checks can 41 // be performed without the need for any locking. The boolean can only be 42 // trusted if the epoch of the state is the same as the epoch_id() of the 43 // watermark. Incrementing the epoch_id() will implicitly initiate a new lazy 44 // stack snapshot, and trigger processing on it as needed, due to the cached 45 // epoch of the state being outdated. When the snapshot is_done for the current 46 // epoch_id(), there is no need to do anything further. 47 class StackWatermarkState : public AllStatic { 48 public: is_done(uint32_t state)49 inline static bool is_done(uint32_t state) { 50 return state & 1; 51 } 52 epoch(uint32_t state)53 inline static uint32_t epoch(uint32_t state) { 54 return state >> 1; 55 } 56 create(uint32_t epoch,bool is_done)57 inline static uint32_t create(uint32_t epoch, bool is_done) { 58 return (epoch << 1) | (is_done ? 1u : 0u); 59 } 60 }; 61 62 // The StackWatermark allows lazy incremental concurrent processing of a 63 // snapshot of a stack. The lazy and incremental nature is implemented by 64 // marking a frame (the watermark) from which returns (or other forms of 65 // unwinding) will take a slow path to perform additional processing 66 // required when exposing more frames that were part of the snapshot to 67 // the system. The watermark pointer always denotes the SP of the watermark. 68 // However, active frames can grow and shrink arbitrarily compared to the 69 // snapshot view that is being processed, due to things like c2i adapters, 70 // and various register saving techniques to get into the runtime. Therefore, 71 // in order to cope with the frames growing and shrinking, comparisons 72 // against the watermark are performed with the frame pointer of a given 73 // frame against the watermark (denoting the SP). 74 // 75 // ---------- 76 // | | 77 // | caller | 78 // | | 79 // ---------- 80 // | | <-- frame fp (always above the watermark of the same frame, 81 // | callee | regardless of frame resizing) 82 // | | 83 // ---------- <-- watermark (callee SP from the snapshot, SP at the 84 // point of unwinding, might be above or below 85 // due to frame resizing) 86 class StackWatermark : public CHeapObj<mtInternal> { 87 friend class StackWatermarkFramesIterator; 88 protected: 89 volatile uint32_t _state; 90 volatile uintptr_t _watermark; 91 StackWatermark* _next; 92 JavaThread* _jt; 93 StackWatermarkFramesIterator* _iterator; 94 Mutex _lock; 95 StackWatermarkKind _kind; 96 StackWatermark* _linked_watermark; 97 98 void process_one(); 99 100 void update_watermark(); 101 void yield_processing(); 102 static bool has_barrier(const frame& f); 103 void ensure_safe(const frame& f); 104 void assert_is_frame_safe(const frame& f) NOT_DEBUG_RETURN; 105 bool is_frame_safe(const frame& f); 106 107 // API for consumers of the stack watermark barrier. 108 // The rule for consumers is: do not perform thread transitions 109 // or take locks of rank >= special. This is all very special code. 110 virtual uint32_t epoch_id() const = 0; 111 virtual void process(const frame& f, RegisterMap& register_map, void* context) = 0; 112 virtual void start_processing_impl(void* context); 113 114 // Set process_on_iteration to false if you don't want to move the 115 // watermark when new frames are discovered from stack walkers, as 116 // opposed to due to frames being unwound by the owning thread. process_on_iteration()117 virtual bool process_on_iteration() { return true; } 118 119 bool processing_started(uint32_t state) const; 120 bool processing_completed(uint32_t state) const; 121 122 public: 123 StackWatermark(JavaThread* jt, StackWatermarkKind kind, uint32_t epoch); 124 virtual ~StackWatermark(); 125 126 127 // StackWatermarkSet support kind() const128 StackWatermarkKind kind() const { return _kind; } next() const129 StackWatermark* next() const { return _next; } set_next(StackWatermark * n)130 void set_next(StackWatermark* n) { _next = n; } 131 132 void link_watermark(StackWatermark* watermark); 133 DEBUG_ONLY(StackWatermark* linked_watermark() const { return _linked_watermark; }) 134 135 uintptr_t watermark(); 136 uintptr_t last_processed(); 137 138 bool processing_started() const; 139 bool processing_started_acquire() const; 140 bool processing_completed() const; 141 bool processing_completed_acquire() const; 142 143 void before_unwind(); 144 void after_unwind(); 145 146 void on_iteration(const frame& f); 147 void on_safepoint(); 148 void start_processing(); 149 void finish_processing(void* context); 150 }; 151 152 #endif // SHARE_RUNTIME_STACKWATERMARK_HPP 153