< prev index next > src/hotspot/share/asm/codeBuffer.hpp
Print this page
#define SHARE_ASM_CODEBUFFER_HPP
#include "code/oopRecorder.hpp"
#include "code/relocInfo.hpp"
#include "compiler/compiler_globals.hpp"
+ #include "runtime/os.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/linkedlist.hpp"
#include "utilities/resizeableResourceHash.hpp"
// This class represents a stream of code and associated relocations.
// There are a few in each CodeBuffer.
// They are filled concurrently, and concatenated at the end.
class CodeSection {
friend class CodeBuffer;
+ friend class SCCReader;
public:
typedef int csize_t; // code size type; would be size_t except for history
private:
address _start; // first byte of contents (instructions)
// Return true if there was an expansion.
bool maybe_expand_to_ensure_remaining(csize_t amount);
#ifndef PRODUCT
void decode();
- void print(const char* name);
+ void print_on(outputStream* st, const char* name);
#endif //PRODUCT
};
#ifndef PRODUCT
- class AsmRemarkCollection;
- class DbgStringCollection;
+ class CHeapString : public CHeapObj<mtCode> {
+ public:
+ CHeapString(const char* str) : _string(os::strdup(str)) {}
+ ~CHeapString() {
+ os::free((void*)_string);
+ _string = nullptr;
+ }
+ const char* string() const { return _string; }
+
+ private:
+ const char* _string;
+ };
+
+ class AsmRemarkCollection : public CHeapObj<mtCode> {
+ public:
+ AsmRemarkCollection() : _ref_cnt(1), _remarks(nullptr), _next(nullptr) {}
+ ~AsmRemarkCollection() {
+ assert(is_empty(), "Must 'clear()' before deleting!");
+ assert(_ref_cnt == 0, "No uses must remain when deleting!");
+ }
+ AsmRemarkCollection* reuse() {
+ precond(_ref_cnt > 0);
+ return _ref_cnt++, this;
+ }
+
+ const char* insert(uint offset, const char* remark);
+ const char* lookup(uint offset) const;
+ const char* next(uint offset) const;
+
+ bool is_empty() const { return _remarks == nullptr; }
+ uint clear();
+
+ template<typename Function>
+ bool iterate(Function function) const { // lambda enabled API
+ if (_remarks != nullptr) {
+ Cell* tmp = _remarks;
+ do {
+ if(!function(tmp->offset, tmp->string())) {
+ return false;
+ }
+ tmp = tmp->next;
+ } while (tmp != _remarks);
+ }
+ return true;
+ }
+
+ private:
+ struct Cell : CHeapString {
+ Cell(const char* remark, uint offset) :
+ CHeapString(remark), offset(offset), prev(nullptr), next(nullptr) {}
+ void push_back(Cell* cell) {
+ Cell* head = this;
+ Cell* tail = prev;
+ tail->next = cell;
+ cell->next = head;
+ cell->prev = tail;
+ prev = cell;
+ }
+ uint offset;
+ Cell* prev;
+ Cell* next;
+ };
+ uint _ref_cnt;
+ Cell* _remarks;
+ // Using a 'mutable' iteration pointer to allow 'const' on lookup/next (that
+ // does not change the state of the list per se), supportig a simplistic
+ // iteration scheme.
+ mutable Cell* _next;
+ };
// The assumption made here is that most code remarks (or comments) added to
// the generated assembly code are unique, i.e. there is very little gain in
// trying to share the strings between the different offsets tracked in a
// buffer (or blob).
class AsmRemarks {
public:
AsmRemarks();
~AsmRemarks();
+ static void init(AsmRemarks& asm_remarks);
+
const char* insert(uint offset, const char* remstr);
bool is_empty() const;
void share(const AsmRemarks &src);
uint print(uint offset, outputStream* strm = tty) const;
// For testing purposes only.
const AsmRemarkCollection* ref() const { return _remarks; }
+ template<typename Function>
+ bool iterate(Function function) const { return _remarks->iterate(function); }
+
private:
AsmRemarkCollection* _remarks;
};
+ class DbgStringCollection : public CHeapObj<mtCode> {
+ public:
+ DbgStringCollection() : _ref_cnt(1), _strings(nullptr) {}
+ ~DbgStringCollection() {
+ assert(is_empty(), "Must 'clear()' before deleting!");
+ assert(_ref_cnt == 0, "No uses must remain when deleting!");
+ }
+ DbgStringCollection* reuse() {
+ precond(_ref_cnt > 0);
+ return _ref_cnt++, this;
+ }
+
+ const char* insert(const char* str);
+ const char* lookup(const char* str) const;
+
+ bool is_empty() const { return _strings == nullptr; }
+ uint clear();
+
+ template<typename Function>
+ bool iterate(Function function) const { // lambda enabled API
+ if (_strings != nullptr) {
+ Cell* tmp = _strings;
+ do {
+ if (!function(tmp->string())) {
+ return false;
+ }
+ tmp = tmp->next;
+ } while (tmp != _strings);
+ }
+ return true;
+ }
+
+ private:
+ struct Cell : CHeapString {
+ Cell(const char* dbgstr) :
+ CHeapString(dbgstr), prev(nullptr), next(nullptr) {}
+ void push_back(Cell* cell) {
+ Cell* head = this;
+ Cell* tail = prev;
+ tail->next = cell;
+ cell->next = head;
+ cell->prev = tail;
+ prev = cell;
+ }
+ Cell* prev;
+ Cell* next;
+ };
+ uint _ref_cnt;
+ Cell* _strings;
+ };
+
// The assumption made here is that the number of debug strings (with a fixed
// address requirement) is a rather small set per compilation unit.
class DbgStrings {
public:
DbgStrings();
~DbgStrings();
+ static void init(DbgStrings& dbg_strings);
+
const char* insert(const char* dbgstr);
bool is_empty() const;
void share(const DbgStrings &src);
void clear();
// For testing purposes only.
const DbgStringCollection* ref() const { return _strings; }
+ template<typename Function>
+ bool iterate(Function function) const { return _strings->iterate(function); }
+
private:
DbgStringCollection* _strings;
};
#endif // not PRODUCT
// addresses in a sibling section.
class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) {
friend class CodeSection;
friend class StubCodeGenerator;
+ friend class SCCReader;
private:
// CodeBuffers must be allocated on the stack except for a single
// special case during expansion which is handled internally. This
// is done to guarantee proper cleanup of resources.
#ifndef PRODUCT
public:
// Printing / Decoding
// decodes from decode_begin() to code_end() and sets decode_begin to end
void decode();
- void print();
+ void print_on(outputStream* st);
#endif
// Directly disassemble code buffer.
void decode(address start, address end);
// The following header contains architecture-specific implementations
< prev index next >