CACAO
Segment.hpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/Segment.hpp - Segment
2 
3  Copyright (C) 2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 #ifndef _JIT_COMPILER2_SEGMENT
26 #define _JIT_COMPILER2_SEGMENT
27 
28 #include "vm/types.hpp"
29 #include <cassert>
32 #include <algorithm>
33 
34 #include "toolbox/OStream.hpp"
35 
36 namespace cacao {
37 namespace jit {
38 namespace compiler2 {
39 
40 // forward declarations
41 class CodeMemory;
42 
43 template <typename Tag, typename RefCategory>
44 class SegRef;
45 
46 template <class Type>
47 class SegmentTag;
48 
49 template <typename Tag>
50 struct classcomp {
51  bool operator() (const SegmentTag<Tag> *lhs, const SegmentTag<Tag> *rhs) const {
52  return *lhs<*rhs;
53  }
54 };
55 
56 #if 0
57 template <typename Tag>
58 bool operator<(SegmentTag<Tag> *lhs, SegmentTag<Tag> *rhs) {
59  LOG2("non-member Segment::operator<"<<nl);
60  return (*lhs) < (*rhs);
61 }
62 
63 template <typename Tag>
64 bool operator==(SegmentTag<Tag> *lhs, SegmentTag<Tag> *rhs) {
65  LOG2("non-member Segment::operator=="<<nl);
66  return (*lhs) == (*rhs);
67 }
68 #endif
69 
72 
73 
74 /**
75  * A segment of the code memory
76  */
77 template <typename Tag, typename RefCategory>
78 class Segment {
79 public:
80  /**
81  * Prevent mixing indices.
82  *
83  * See Item 18 in "Efficient C++" @cite Meyers2005.
84  */
85  struct IdxTy {
86  std::size_t idx;
87 
88  /// default constructor
89  IdxTy() : idx(-1) {}
90  /// explicit constructor
91  explicit IdxTy(std::size_t idx) : idx(idx) {}
92  /// copy assignment operator
93  IdxTy& operator=(const IdxTy &other) {
94  idx = other.idx;
95  return *this;
96  }
97  IdxTy operator+(std::size_t i) const {
98  return IdxTy(idx + i);
99  }
100  IdxTy operator-(std::size_t i) const {
101  return IdxTy(idx - i);
102  }
103  bool operator==(const IdxTy &other) const {
104  return idx == other.idx;
105  }
106  #if 0
107  bool operator==(std::size_t other) const {
108  return idx == other;
109  }
110  #endif
111  };
113 private:
114  typedef typename alloc::map<SegmentTag<Tag>*,IdxTy,classcomp<Tag> >::type EntriesTy;
116  alloc::vector<u1>::type content; ///< content of the segment
117  EntriesTy entries; ///< tagged entries
118 
119  /// invalid index
120  static inline IdxTy invalid_index() { return IdxTy(-1); }
121 
122  /// insert tag
123  IdxTy insert_tag(SegmentTag<Tag>* tag, IdxTy o) {
124  entries[tag] = o;
125  return o;
126  }
127  /// contains tag
129  return entries.find(tag) != entries.end();
130  }
131  /// get index
133  typename EntriesTy::const_iterator i = entries.find(tag);
134  if ( i == entries.end()) return invalid_index();
135  return i->second;
136  }
137 public:
138  /// Constructor
139  Segment(CodeMemory *CM) : CM(CM), content() {}
140  /// Constructor with default capacity
141  Segment(CodeMemory *CM, IdxTy capacity) : CM(CM), content() {
142  content.reserve(capacity);
143  }
144  /// Get containing CodeMemory
145  CodeMemory* get_CodeMemory() const { return CM; }
146  CodeMemory& get_CodeMemory() { return *CM; }
147 
148  /**
149  * get size
150  *
151  * @deprecated this should only be available in the closed variant
152  */
153  std::size_t size() const { return content.size(); }
154 
155  /// is invalid index
156  static inline bool is_invalid(IdxTy idx) { return idx == invalid_index(); }
157 
158  /**
159  * Get the start index of next Reference in line.
160  *
161  * Note that the index may or may not be already present. In the later
162  * case the index of the future Reference will be returned
163  */
164  IdxTy get_following_index() const {
165  return getFollowingIndex(*this,RefCategory());
166  }
167 
168  /**
169  * get start address
170  *
171  * @deprecated this should only be available in the closed variant
172  */
174  return &content.front();
175  }
176  /**
177  * get end address
178  *
179  * @deprecated this should only be available in the closed variant
180  */
181  u1* get_end() {
182  return get_start() + size();
183  }
184  /// write content
185  u1& operator[](IdxTy i) {
186  return operator[](i.idx);
187  }
188  u1& operator[](std::size_t i) {
189  assert(i >= 0);
190  assert(i < content.size());
191  return content[i];
192  }
193  /// get content
194  u1 at(std::size_t i) const {
195  assert(i < content.size());
196  return content[i];
197  }
198  /**
199  * reverse content
200  *
201  * @deprecated this should only be available in the closed variant
202  */
203  void reverse() {
204  std::reverse(content.begin(), content.end());
205  }
206 
207  /// get a new reference to the segment
208  Ref get_Ref(std::size_t t) {
209  std::size_t start = content.size();
210  content.resize(start + t);
211  return Ref(this,IdxTy(start),t);
212  }
213 
214  /**
215  * get a reference to the segment
216  *
217  * @todo replace with getter for tag
218  */
219  Ref get_Ref(IdxTy idx, std::size_t t) {
220  return Ref(this,idx,t);
221  }
222 
223  /// insert tag
224  template<typename Tag2>
225  IdxTy insert_tag(Tag2 tag, const Ref &ref) {
226  return insert_tag(new Tag2(tag),ref.get_begin());
227  }
228  /// insert tag
229  template<typename Tag2>
230  IdxTy insert_tag(Tag2 tag) {
231  return insert_tag(new Tag2(tag),get_following_index());
232  }
233  #if 0
234  /// insert tag
235  void insert_tag(SegmentTag<Tag>* tag, const Ref &ref) {
236  insert_tag(tag,ref.get_index());
237  }
238  /// insert tag
239  void insert_tag(SegmentTag<Tag>* tag) {
240  insert_tag(tag,content.size());
241  }
242  #endif
243  /// contains tag
244  template<typename Tag2>
245  bool contains_tag(Tag2 tag) const {
246  return contains_tag_intern(&tag);
247  }
248  /**
249  * get the index of a tag
250  *
251  * @return the index of the tag or end() if not found
252  */
253  template<typename Tag2>
254  IdxTy get_index(Tag2 tag) const {
255  return get_index_intern(&tag);
256  }
257  #if 0
258  bool contains_tag(const SegmentTag<Tag> &tag) const {
259  return entries.find(&tag) != entries.end();
260  }
261  #endif
262 
263  OStream& print(OStream &OS) const {
264  for(typename EntriesTy::const_iterator i = entries.begin(), e = entries.end() ;
265  i != e ; ++i) {
266  OS << "key: ";
267  i->first->print(OS);
268  OS << " value: " << i->second << nl;
269  }
270  return OS;
271  }
272 
273  virtual ~Segment() {
274  for (typename EntriesTy::iterator i= entries.begin(), e = entries.end();
275  i != e; ++i) {
276  delete i->first;
277  }
278  }
279 
280  friend class SegRef<Tag,RefCategory>;
281 };
282 
283 /**
284  * Segment reference
285  *
286  * Segment references used to write data into the Segment and for linking.
287  * Segments are position independent.
288  *
289  * It can be used like an u1 array.
290  */
291 template <typename Tag, typename RefCategory>
292 class SegRef {
293 public:
294  typedef RefCategory ref_category;
296 private:
299  std::size_t _size;
301  : parent(parent), index(index), _size(_size) {}
302 public:
303  /// Copy Constructor
304  SegRef(const SegRef<Tag,RefCategory> &other) : parent(other.parent),
305  index(other.index), _size(other.size()) {}
306  /// Copy assignment operator
308  parent = other.parent;
309  index = other.index;
310  _size = other.size();
311  return *this;
312  }
313  /// Get a sub-segment
314  SegRef operator+(std::size_t v) {
315  assert(v >= 0);
316  assert(_size - v >= 0);
317  return SegRef(parent, getAddStartIndex(*this,v,RefCategory()), _size - v);
318  }
319  /// access data
320  u1& operator[](std::size_t i) {
321  return doAccess(*this,i,RefCategory());
322  }
323 
325  return operator[](i.idx);
326  }
327  /// Get containing segment
329  return parent;
330  }
332  return *parent;
333  }
334  /**
335  * Get the index of the first element.
336  *
337  * Return the index of the first element with respect to RefCategory
338  * (i.e. the element written by operator[0]). Note that get_begin() might
339  * be greater than get_end() depending on RefCategory.
340  *
341  * @see get_end()
342  */
343  IdxTy get_begin() const {
344  return getBegin(*this,RefCategory());
345  }
346  /**
347  * Get the index of the first element after the reference.
348  *
349  * Return the index of the first element after the reference with respect
350  * to RefCategory (i.e. the element that would be written by
351  * operator[size()], which is not allowed). Note that get_begin() might
352  * be greater than get_end() depending on RefCategory.
353  *
354  * @see get_begin()
355  */
356  IdxTy get_end() const {
357  return getEnd(*this,RefCategory());
358  }
359  /**
360  * Get the raw start index.
361  *
362  * This returns the begin (i.e. the lowest index) of the raw
363  * reference. It does not take the RefCategory into account. Also
364  * the assertion get_index_begin_raw() <= get_index_end_raw() always holds.
365  *
366  * In most cases the use of get_begin() and get_end() is preferable.
367  *
368  * @see get_index_end_raw()
369  * @see get_begin()
370  * @see get_end()
371  */
373  return index;
374  }
375  /**
376  * Get the raw end index.
377  *
378  * This returns the end (i.e. last index plus one) of the raw
379  * reference. It does not take the RefCategory into account. Also
380  * the assertion get_index_begin_raw() <= get_index_end_raw() always holds.
381  *
382  * In most cases the use of get_begin() and get_end() is preferable.
383  *
384  * @see get_index_begin_raw()
385  * @see get_begin()
386  * @see get_end()
387  */
389  return index + _size;
390  }
391  /// size of the reference
392  std::size_t size() const {
393  return _size;
394  }
395  friend class Segment<Tag,RefCategory>;
396 };
397 
398 // specialization for Normal Segments
399 #if 0
400 template <typename Tag>
401 inline u1& SegRef<Tag,NormalRefCategory>::operator[](std::size_t i) {
402  assert(i < size());
403  return (*parent)[index.idx + i];
404 }
405 // specialization for Normal Segments
406 template <typename Tag>
407 inline u1& SegRef<Tag,ReverseRefCategory>::operator[](std::size_t i) {
408  assert(i < size());
409  return (*parent)[index.idx + size() - i - 1];
410 }
411 #endif
412 /// access data
413 template <typename Tag, typename RefCategory>
414 inline u1&
416  assert(i < ref.size());
417  return ref.get_Segment()[ref.get_index_begin_raw().idx + i];
418 }
419 /// access data
420 template <typename Tag, typename RefCategory>
421 inline u1&
423  assert(i < ref.size());
424  return ref.get_Segment()[ref.get_index_end_raw().idx - 1 - i];
425 }
426 
427 /// get subreference
428 template <typename Tag, typename RefCategory>
429 inline typename SegRef<Tag,RefCategory>::IdxTy
431  return ref.get_index_begin_raw() + v;
432 }
433 /// get subreference
434 template <typename Tag, typename RefCategory>
435 inline typename SegRef<Tag,RefCategory>::IdxTy
437  return ref.get_index_begin_raw();
438 }
439 
440 /// get first index
441 template <typename Tag, typename RefCategory>
442 inline typename SegRef<Tag,RefCategory>::IdxTy
444  return ref.get_index_begin_raw();
445 }
446 /// get first index
447 template <typename Tag, typename RefCategory>
448 inline typename SegRef<Tag,RefCategory>::IdxTy
450  return ref.get_index_end_raw() -1;
451 }
452 
453 /// get last but one index
454 template <typename Tag, typename RefCategory>
455 inline typename SegRef<Tag,RefCategory>::IdxTy
457  return ref.get_index_end_raw();
458 }
459 /// get last but one index
460 template <typename Tag, typename RefCategory>
461 inline typename SegRef<Tag,RefCategory>::IdxTy
463  return ref.get_index_begin_raw() -1;
464 }
465 
466 // get last index of a segment
467 template <typename Tag, typename RefCategory>
468 inline typename Segment<Tag,RefCategory>::IdxTy
470  return typename Segment<Tag,RefCategory>::IdxTy(ref.size());
471 }
472 // get last index of a segment
473 template <typename Tag, typename RefCategory>
474 inline typename Segment<Tag,RefCategory>::IdxTy
476  return typename Segment<Tag,RefCategory>::IdxTy(ref.size() - 1);
477 }
478 
479 template <class Type>
480 class SegmentTag {
481 protected:
482  SegmentTag(Type type) : type(type) {}
483  virtual u8 hash() const = 0;
484 public:
485  bool operator==(const SegmentTag& other) const {
486  return type == other.type && hash() == other.hash();
487  }
488  bool operator<(const SegmentTag& other) const {
489  if (type == other.type)
490  return hash() < other.hash();
491  return type < other.type;
492  }
493  virtual OStream& print(OStream &OS) const = 0;
494  virtual ~SegmentTag() {};
495 private:
496  Type type;
497 };
498 
499 template <class Type>
500 OStream& operator<<(OStream &OS, SegmentTag<Type> &tag) {
501  return tag.print(OS);
502 }
503 template <class Type>
504 inline OStream& operator<<(OStream &OS, SegmentTag<Type> *tag) {
505  return OS << *tag;
506 }
507 
508 
509 template <class Type, class ConstTy, Type t>
510 class ConstTag : public SegmentTag<Type> {
511 protected:
512  virtual u8 hash() const {
513  if (sizeof(ConstTy) == sizeof(u1))
514  return u8(*reinterpret_cast<const u1*>(&c));
515  if (sizeof(ConstTy) == sizeof(u2))
516  return u8(*reinterpret_cast<const u2*>(&c));
517  if (sizeof(ConstTy) == sizeof(u4))
518  return u8(*reinterpret_cast<const u4*>(&c));
519  return *reinterpret_cast<const u8*>(&c);
520  }
521 public:
522  ConstTag(ConstTy c) : SegmentTag<Type>(t), c(c) {}
523  virtual OStream& print(OStream &OS) const {
524  return OS << "ConstTag Type: " << t << " ptr: " << c;
525  }
526  virtual ~ConstTag() {}
527 private:
528  ConstTy c;
529 };
530 
531 template <class Type, class Ptr, Type t>
532 class PointerTag : public SegmentTag<Type> {
533 protected:
534  virtual u8 hash() const {
535  return u8(ptr);
536  }
537 public:
538  PointerTag(Ptr *ptr) : SegmentTag<Type>(t), ptr(ptr) {}
539  virtual OStream& print(OStream &OS) const {
540  return OS << "PointerTag Type: " << t << " ptr: " << ptr;
541  }
542  virtual ~PointerTag() {}
543 private:
544  Ptr *ptr;
545 };
546 
547 } // end namespace compiler2
548 } // end namespace jit
549 } // end namespace cacao
550 
551 #endif /* _JIT_COMPILER2_SEGMENT */
552 
553 
554 /*
555  * These are local overrides for various environment variables in Emacs.
556  * Please do not remove this and leave it at the end of the file, where
557  * Emacs will automagically detect them.
558  * ---------------------------------------------------------------------
559  * Local variables:
560  * mode: c++
561  * indent-tabs-mode: t
562  * c-basic-offset: 4
563  * tab-width: 4
564  * End:
565  * vim:noexpandtab:sw=4:ts=4:
566  */
std::size_t index
IdxTy get_index_end_raw() const
Get the raw end index.
Definition: Segment.hpp:388
bool operator==(const IdxTy &other) const
Definition: Segment.hpp:103
OStream & print(OStream &OS) const
Definition: Segment.hpp:263
bool operator==(const SegmentTag &other) const
Definition: Segment.hpp:485
static IdxTy invalid_index()
invalid index
Definition: Segment.hpp:120
bool contains_tag_intern(SegmentTag< Tag > *tag) const
contains tag
Definition: Segment.hpp:128
virtual OStream & print(OStream &OS) const
Definition: Segment.hpp:539
alloc::map< SegmentTag< Tag > *, IdxTy, classcomp< Tag > >::type EntriesTy
Definition: Segment.hpp:114
u1 & operator[](std::size_t i)
Definition: Segment.hpp:188
SegRef(const SegRef< Tag, RefCategory > &other)
Copy Constructor.
Definition: Segment.hpp:304
virtual OStream & print(OStream &OS) const =0
SegRef< Tag, RefCategory >::IdxTy getEnd(const SegRef< Tag, RefCategory > &ref, NormalRefCategory)
get last but one index
Definition: Segment.hpp:456
IdxTy insert_tag(Tag2 tag, const Ref &ref)
insert tag
Definition: Segment.hpp:225
alloc::vector< u1 >::type content
content of the segment
Definition: Segment.hpp:116
Segment(CodeMemory *CM)
Constructor.
Definition: Segment.hpp:139
u1 at(std::size_t i) const
get content
Definition: Segment.hpp:194
SegRef & operator=(const SegRef< Tag, RefCategory > &other)
Copy assignment operator.
Definition: Segment.hpp:307
IdxTy insert_tag(Tag2 tag)
insert tag
Definition: Segment.hpp:230
Segment< Tag, RefCategory >::IdxTy getFollowingIndex(const Segment< Tag, RefCategory > &ref, NormalRefCategory)
Definition: Segment.hpp:469
uint8_t u1
Definition: types.hpp:40
SegRef(Segment< Tag, RefCategory > *parent, IdxTy index, std::size_t _size)
Definition: Segment.hpp:300
std::size_t size() const
get size
Definition: Segment.hpp:153
Ref get_Ref(IdxTy idx, std::size_t t)
get a reference to the segment
Definition: Segment.hpp:219
CodeMemory & get_CodeMemory()
Definition: Segment.hpp:146
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
EntriesTy entries
tagged entries
Definition: Segment.hpp:117
static bool is_invalid(IdxTy idx)
is invalid index
Definition: Segment.hpp:156
u1 & operator[](IdxTy i)
write content
Definition: Segment.hpp:185
void reverse()
reverse content
Definition: Segment.hpp:203
u1 * get_end()
get end address
Definition: Segment.hpp:181
IdxTy(std::size_t idx)
explicit constructor
Definition: Segment.hpp:91
Segment< Tag, RefCategory > * get_Segment() const
Get containing segment.
Definition: Segment.hpp:328
uint16_t u2
Definition: types.hpp:43
IdxTy get_index_begin_raw() const
Get the raw start index.
Definition: Segment.hpp:372
CodeMemory * get_CodeMemory() const
Get containing CodeMemory.
Definition: Segment.hpp:145
virtual u8 hash() const
Definition: Segment.hpp:512
std::vector< T, Allocator< T > > type
Definition: vector.hpp:38
virtual u8 hash() const
Definition: Segment.hpp:534
IdxTy operator-(std::size_t i) const
Definition: Segment.hpp:100
uint64_t u8
Definition: types.hpp:49
IdxTy get_end() const
Get the index of the first element after the reference.
Definition: Segment.hpp:356
bool operator()(const SegmentTag< Tag > *lhs, const SegmentTag< Tag > *rhs) const
Definition: Segment.hpp:51
Segment< Tag, RefCategory >::IdxTy IdxTy
Definition: Segment.hpp:295
Prevent mixing indices.
Definition: Segment.hpp:85
bool contains_tag(Tag2 tag) const
contains tag
Definition: Segment.hpp:245
Simple stream class for formatted output.
Definition: OStream.hpp:141
u1 & operator[](std::size_t i)
access data
Definition: Segment.hpp:320
Segment< Tag, RefCategory > * parent
Definition: Segment.hpp:297
Segment< Tag, RefCategory > & get_Segment()
Definition: Segment.hpp:331
std::size_t size() const
size of the reference
Definition: Segment.hpp:392
u1 & doAccess(SegRef< Tag, RefCategory > &ref, std::size_t i, NormalRefCategory)
access data
Definition: Segment.hpp:415
jlong tag
Definition: jvmti.h:395
MIIterator i
IdxTy operator+(std::size_t i) const
Definition: Segment.hpp:97
#define LOG2(STMT)
Definition: logging.hpp:93
IdxTy & operator=(const IdxTy &other)
copy assignment operator
Definition: Segment.hpp:93
IdxTy insert_tag(SegmentTag< Tag > *tag, IdxTy o)
insert tag
Definition: Segment.hpp:123
Segment(CodeMemory *CM, IdxTy capacity)
Constructor with default capacity.
Definition: Segment.hpp:141
OStream & OS
bool operator==(const UseDef &lhs, const UseDef &rhs)
IdxTy get_index(Tag2 tag) const
get the index of a tag
Definition: Segment.hpp:254
IdxTy get_following_index() const
Get the start index of next Reference in line.
Definition: Segment.hpp:164
MIIterator e
SegRef< Tag, RefCategory >::IdxTy getBegin(const SegRef< Tag, RefCategory > &ref, NormalRefCategory)
get first index
Definition: Segment.hpp:443
A segment of the code memory.
Definition: Segment.hpp:78
uint32_t u4
Definition: types.hpp:46
SegRef operator+(std::size_t v)
Get a sub-segment.
Definition: Segment.hpp:314
SegRef< Tag, RefCategory > Ref
Definition: Segment.hpp:112
virtual u8 hash() const =0
IdxTy()
default constructor
Definition: Segment.hpp:89
Segment reference.
Definition: Segment.hpp:44
u1 * get_start()
get start address
Definition: Segment.hpp:173
SegRef< Tag, RefCategory >::IdxTy getAddStartIndex(SegRef< Tag, RefCategory > &ref, std::size_t v, NormalRefCategory)
get subreference
Definition: Segment.hpp:430
IdxTy get_begin() const
Get the index of the first element.
Definition: Segment.hpp:343
bool operator<(const SegmentTag &other) const
Definition: Segment.hpp:488
IdxTy get_index_intern(SegmentTag< Tag > *tag) const
get index
Definition: Segment.hpp:132
Nl nl
Definition: OStream.cpp:56
Ref get_Ref(std::size_t t)
get a new reference to the segment
Definition: Segment.hpp:208
LoopTreeGraph * parent
virtual OStream & print(OStream &OS) const
Definition: Segment.hpp:523