/* * Copyright (c) 1998, 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. *
*/
// Interface for generating the frame map for compiled code. A frame map // describes for a specific pc whether each register and frame stack slot is: // Oop - A GC root for current frame // Dead - Dead; can be Zapped for debugging // CalleeXX - Callee saved; also describes which caller register is saved // DerivedXX - A derived oop; original oop is described. // // OopMapValue describes a single OopMap entry
enumclass DerivedPointerIterationMode; class frame; class RegisterMap; class OopClosure; class CodeBlob; class ImmutableOopMap;
enumclass derived_pointer : intptr_t {};
class OopMapValue: public StackObj { friendclass VMStructs; private: short _value; int value() const { return _value; } void set_value(int value) { _value = value; } short _content_reg;
void set_content_reg(VMReg r) { if (is_callee_saved()) { // This can never be a stack location, so we don't need to transform it.
assert(r->is_reg(), "Trying to callee save a stack location");
} elseif (is_derived_oop()) {
assert (r->is_valid(), "must have a valid VMReg");
} else {
assert (!r->is_valid(), "valid VMReg not allowed");
}
_content_reg = r->value();
}
class OopMap: public ResourceObj { friendclass OopMapStream; friendclass VMStructs; friendclass OopMapSet; friendclass OopMapSort; private: int _pc_offset; // offset in the code that this OopMap corresponds to int _omv_count; // number of OopMapValues in the stream int _num_oops; // number of oops int _index; // index in OopMapSet bool _has_derived_oops;
CompressedWriteStream* _write_stream;
debug_only( OopMapValue::oop_types* _locs_used; int _locs_length;)
// Construction // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd // slots to hold 4-byte values like ints and floats in the LP64 build. void set_oop ( VMReg local); void set_narrowoop(VMReg local); void set_callee_saved( VMReg local, VMReg caller_machine_register ); void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
class OopMapSet : public ResourceObj { friendclass VMStructs; private:
GrowableArray<OopMap*> _list;
int add(OopMap* value) { return _list.append(value); }
public:
OopMapSet();
// returns the number of OopMaps in this OopMapSet int size() const { return _list.length(); } // returns the OopMap at a given index
OopMap* at(int index) const { return _list.at(index); }
// Collect OopMaps. int add_gc_map(int pc, OopMap* map);
// Methods oops_do() and all_do() filter out NULL oops and // oop == CompressedOops::base() before passing oops // to closures.
template <typename OopFnT, typename DerivedOopFnT, typename ValueFilterT> class OopMapDo;
class ImmutableOopMap { friendclass OopMapStream; friendclass VMStructs; template <typename OopFnT, typename DerivedOopFnT, typename ValueFilterT> friendclass OopMapDo; #ifdef ASSERT friendclass ImmutableOopMapBuilder; #endif private: int _count; // contains the number of entries in this OopMap int _num_oops; bool _has_derived_oops;
class ImmutableOopMapSet; class ImmutableOopMap; class OopMapSet;
class ImmutableOopMapPair { friendclass VMStructs; private: int _pc_offset; // program counter offset from the beginning of the method int _oopmap_offset; // offset in the data in the ImmutableOopMapSet where the ImmutableOopMap is located public:
ImmutableOopMapPair(int pc_offset, int oopmap_offset) : _pc_offset(pc_offset), _oopmap_offset(oopmap_offset) {
assert(pc_offset >= 0 && oopmap_offset >= 0, "check");
} const ImmutableOopMap* get_from(const ImmutableOopMapSet* set) const;
int pc_offset() const { return _pc_offset; } int oopmap_offset() const { return _oopmap_offset; }
};
class ImmutableOopMapSet { friendclass VMStructs; private: int _count; // nr of ImmutableOopMapPairs in the Set int _size; // nr of bytes including ImmutableOopMapSet itself
class OopMapStream : public StackObj { private:
CompressedReadStream _stream; int _size; int _position; bool _valid_omv;
OopMapValue _omv; void find_next();
// Derived pointer support. This table keeps track of all derived points on a // stack. It is cleared before each scavenge/GC. During the traversal of all // oops, it is filled in with references to all locations that contains a // derived oop (assumed to be very few). When the GC is complete, the derived // pointers are updated based on their base pointers new value and an offset. #if COMPILER2_OR_JVMCI class DerivedPointerTable : public AllStatic { friendclass VMStructs; private: class Entry; staticbool _active; // do not record pointers for verify pass etc.
public: staticvoid clear(); // Called before scavenge/GC staticvoid add(derived_pointer* derived, oop *base); // Called during scavenge/GC staticvoid update_pointers(); // Called after scavenge/GC staticbool is_empty(); staticbool is_active() { return _active; } staticvoid set_active(bool value) { _active = value; }
};
// A utility class to temporarily "deactivate" the DerivedPointerTable. // (Note: clients are responsible for any MT-safety issues) class DerivedPointerTableDeactivate: public StackObj { private: bool _active; public:
DerivedPointerTableDeactivate() {
_active = DerivedPointerTable::is_active(); if (_active) {
DerivedPointerTable::set_active(false);
}
}
~DerivedPointerTableDeactivate() {
assert(!DerivedPointerTable::is_active(), "Inconsistency: not MT-safe"); if (_active) {
DerivedPointerTable::set_active(true);
}
}
}; #endif// COMPILER2_OR_JVMCI
#endif// SHARE_COMPILER_OOPMAP_HPP
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet)
¤
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.