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