140 // An opaque struct of heap-word width, so that HeapWord* can be a generic
141 // pointer into the heap. We require that object sizes be measured in
142 // units of heap words, so that that
143 // HeapWord* hw;
144 // hw += oop(hw)->foo();
145 // works, where foo is a method (like size or scavenge) that returns the
146 // object size.
147 class HeapWord {
148 friend class VMStructs;
149 private:
150 char* i;
151 #ifndef PRODUCT
152 public:
153 char* value() { return i; }
154 #endif
155 };
156
157 // Analogous opaque struct for metadata allocated from
158 // metaspaces.
159 class MetaWord {
160 friend class VMStructs;
161 private:
162 char* i;
163 };
164
165 // HeapWordSize must be 2^LogHeapWordSize.
166 const int HeapWordSize = sizeof(HeapWord);
167 #ifdef _LP64
168 const int LogHeapWordSize = 3;
169 #else
170 const int LogHeapWordSize = 2;
171 #endif
172 const int HeapWordsPerLong = BytesPerLong / HeapWordSize;
173 const int LogHeapWordsPerLong = LogBytesPerLong - LogHeapWordSize;
174
175 // The larger HeapWordSize for 64bit requires larger heaps
176 // for the same application running in 64bit. See bug 4967770.
177 // The minimum alignment to a heap word size is done. Other
178 // parts of the memory system may require additional alignment
179 // and are responsible for those alignments.
180 #ifdef _LP64
469 inline bool is_size_aligned(size_t size, size_t alignment) {
470 return align_size_up_(size, alignment) == size;
471 }
472
473 inline bool is_ptr_aligned(void* ptr, size_t alignment) {
474 return align_size_up_((intptr_t)ptr, (intptr_t)alignment) == (intptr_t)ptr;
475 }
476
477 inline intptr_t align_size_up(intptr_t size, intptr_t alignment) {
478 return align_size_up_(size, alignment);
479 }
480
481 #define align_size_down_(size, alignment) ((size) & ~((alignment) - 1))
482
483 inline intptr_t align_size_down(intptr_t size, intptr_t alignment) {
484 return align_size_down_(size, alignment);
485 }
486
487 #define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment)))
488
489 inline void* align_ptr_up(void* ptr, size_t alignment) {
490 return (void*)align_size_up((intptr_t)ptr, (intptr_t)alignment);
491 }
492
493 inline void* align_ptr_down(void* ptr, size_t alignment) {
494 return (void*)align_size_down((intptr_t)ptr, (intptr_t)alignment);
495 }
496
497 // Align objects by rounding up their size, in HeapWord units.
498
499 #define align_object_size_(size) align_size_up_(size, MinObjAlignment)
500
501 inline intptr_t align_object_size(intptr_t size) {
502 return align_size_up(size, MinObjAlignment);
503 }
504
505 inline bool is_object_aligned(intptr_t addr) {
506 return addr == align_object_size(addr);
507 }
508
509 // Pad out certain offsets to jlong alignment, in HeapWord units.
510
511 inline intptr_t align_object_offset(intptr_t offset) {
512 return align_size_up(offset, HeapWordsPerLong);
513 }
514
515 inline void* align_pointer_up(const void* addr, size_t size) {
516 return (void*) align_size_up_((uintptr_t)addr, size);
517 }
518
519 // Align down with a lower bound. If the aligning results in 0, return 'alignment'.
520
521 inline size_t align_size_down_bounded(size_t size, size_t alignment) {
522 size_t aligned_size = align_size_down_(size, alignment);
523 return aligned_size > 0 ? aligned_size : alignment;
524 }
525
526 // Clamp an address to be within a specific page
527 // 1. If addr is on the page it is returned as is
528 // 2. If addr is above the page_address the start of the *next* page will be returned
529 // 3. Otherwise, if addr is below the page_address the start of the page will be returned
530 inline address clamp_address_in_page(address addr, address page_address, intptr_t page_size) {
531 if (align_size_down(intptr_t(addr), page_size) == align_size_down(intptr_t(page_address), page_size)) {
532 // address is in the specified page, just return it as is
533 return addr;
534 } else if (addr > page_address) {
535 // address is above specified page, return start of next page
536 return (address)align_size_down(intptr_t(page_address), page_size) + page_size;
|
140 // An opaque struct of heap-word width, so that HeapWord* can be a generic
141 // pointer into the heap. We require that object sizes be measured in
142 // units of heap words, so that that
143 // HeapWord* hw;
144 // hw += oop(hw)->foo();
145 // works, where foo is a method (like size or scavenge) that returns the
146 // object size.
147 class HeapWord {
148 friend class VMStructs;
149 private:
150 char* i;
151 #ifndef PRODUCT
152 public:
153 char* value() { return i; }
154 #endif
155 };
156
157 // Analogous opaque struct for metadata allocated from
158 // metaspaces.
159 class MetaWord {
160 private:
161 char* i;
162 };
163
164 // HeapWordSize must be 2^LogHeapWordSize.
165 const int HeapWordSize = sizeof(HeapWord);
166 #ifdef _LP64
167 const int LogHeapWordSize = 3;
168 #else
169 const int LogHeapWordSize = 2;
170 #endif
171 const int HeapWordsPerLong = BytesPerLong / HeapWordSize;
172 const int LogHeapWordsPerLong = LogBytesPerLong - LogHeapWordSize;
173
174 // The larger HeapWordSize for 64bit requires larger heaps
175 // for the same application running in 64bit. See bug 4967770.
176 // The minimum alignment to a heap word size is done. Other
177 // parts of the memory system may require additional alignment
178 // and are responsible for those alignments.
179 #ifdef _LP64
468 inline bool is_size_aligned(size_t size, size_t alignment) {
469 return align_size_up_(size, alignment) == size;
470 }
471
472 inline bool is_ptr_aligned(void* ptr, size_t alignment) {
473 return align_size_up_((intptr_t)ptr, (intptr_t)alignment) == (intptr_t)ptr;
474 }
475
476 inline intptr_t align_size_up(intptr_t size, intptr_t alignment) {
477 return align_size_up_(size, alignment);
478 }
479
480 #define align_size_down_(size, alignment) ((size) & ~((alignment) - 1))
481
482 inline intptr_t align_size_down(intptr_t size, intptr_t alignment) {
483 return align_size_down_(size, alignment);
484 }
485
486 #define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment)))
487
488 inline void* align_ptr_up(const void* ptr, size_t alignment) {
489 return (void*)align_size_up((intptr_t)ptr, (intptr_t)alignment);
490 }
491
492 inline void* align_ptr_down(void* ptr, size_t alignment) {
493 return (void*)align_size_down((intptr_t)ptr, (intptr_t)alignment);
494 }
495
496 // Align metaspace objects by rounding up to natural word boundary
497
498 inline intptr_t align_metadata_size(intptr_t size) {
499 return align_size_up(size, 1);
500 }
501
502 // Align objects in the Java Heap by rounding up their size, in HeapWord units.
503 // Since the size is given in words this is somewhat of a nop, but
504 // distinguishes it from align_object_size.
505 inline intptr_t align_object_size(intptr_t size) {
506 return align_size_up(size, MinObjAlignment);
507 }
508
509 inline bool is_object_aligned(intptr_t addr) {
510 return addr == align_object_size(addr);
511 }
512
513 // Pad out certain offsets to jlong alignment, in HeapWord units.
514
515 inline intptr_t align_object_offset(intptr_t offset) {
516 return align_size_up(offset, HeapWordsPerLong);
517 }
518
519 // Align down with a lower bound. If the aligning results in 0, return 'alignment'.
520
521 inline size_t align_size_down_bounded(size_t size, size_t alignment) {
522 size_t aligned_size = align_size_down_(size, alignment);
523 return aligned_size > 0 ? aligned_size : alignment;
524 }
525
526 // Clamp an address to be within a specific page
527 // 1. If addr is on the page it is returned as is
528 // 2. If addr is above the page_address the start of the *next* page will be returned
529 // 3. Otherwise, if addr is below the page_address the start of the page will be returned
530 inline address clamp_address_in_page(address addr, address page_address, intptr_t page_size) {
531 if (align_size_down(intptr_t(addr), page_size) == align_size_down(intptr_t(page_address), page_size)) {
532 // address is in the specified page, just return it as is
533 return addr;
534 } else if (addr > page_address) {
535 // address is above specified page, return start of next page
536 return (address)align_size_down(intptr_t(page_address), page_size) + page_size;
|