/* * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
class frame; class JavaThread; class RegisterMap; class StackWatermarkFramesIterator;
// The StackWatermark state is a tuple comprising the last epoch in which // the watermark has been processed, and a boolean denoting whether the whole // processing of the lazy snapshot has been processed or not. It is written // in a way that can be used outside of locks, so that fast path checks can // be performed without the need for any locking. The boolean can only be // trusted if the epoch of the state is the same as the epoch_id() of the // watermark. Incrementing the epoch_id() will implicitly initiate a new lazy // stack snapshot, and trigger processing on it as needed, due to the cached // epoch of the state being outdated. When the snapshot is_done for the current // epoch_id(), there is no need to do anything further. class StackWatermarkState : public AllStatic { public: inlinestaticbool is_done(uint32_t state) { return state & 1;
}
inlinestatic uint32_t epoch(uint32_t state) { return state >> 1;
}
// The StackWatermark allows lazy incremental concurrent processing of a // snapshot of a stack. The lazy and incremental nature is implemented by // marking a frame (the watermark) from which returns (or other forms of // unwinding) will take a slow path to perform additional processing // required when exposing more frames that were part of the snapshot to // the system. The watermark pointer always denotes the SP of the watermark. // However, active frames can grow and shrink arbitrarily compared to the // snapshot view that is being processed, due to things like c2i adapters, // and various register saving techniques to get into the runtime. Therefore, // in order to cope with the frames growing and shrinking, comparisons // against the watermark are performed with the frame pointer of a given // frame against the watermark (denoting the SP). // // ---------- // | | // | caller | // | | // ---------- // | | <-- frame fp (always above the watermark of the same frame, // | callee | regardless of frame resizing) // | | // ---------- <-- watermark (callee SP from the snapshot, SP at the // point of unwinding, might be above or below // due to frame resizing) class StackWatermark : public CHeapObj<mtThread> { friendclass StackWatermarkFramesIterator; protected: volatile uint32_t _state; volatile uintptr_t _watermark;
StackWatermark* _next;
JavaThread* _jt;
StackWatermarkFramesIterator* _iterator;
Mutex _lock;
StackWatermarkKind _kind;
GrowableArrayCHeap<StackWatermark*, mtThread> _linked_watermarks;
// API for consumers of the stack watermark barrier. // The rule for consumers is: do not perform thread transitions // or take locks of rank >= special. This is all very special code. virtual uint32_t epoch_id() const = 0; virtualvoid process(const frame& f, RegisterMap& register_map, void* context) = 0; virtualvoid start_processing_impl(void* context);
// Set process_on_iteration to false if you don't want to move the // watermark when new frames are discovered from stack walkers, as // opposed to due to frames being unwound by the owning thread. virtualbool process_on_iteration() { returntrue; }
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.