516 |
516 |
517 #define align_size_down_(size, alignment) ((size) & ~align_mask_widened((alignment), (size))) |
517 #define align_size_down_(size, alignment) ((size) & ~align_mask_widened((alignment), (size))) |
518 |
518 |
519 #define align_size_up_(size, alignment) (align_size_down_((size) + align_mask(alignment), (alignment))) |
519 #define align_size_up_(size, alignment) (align_size_down_((size) + align_mask(alignment), (alignment))) |
520 |
520 |
521 inline bool is_size_aligned(size_t size, size_t alignment) { |
521 #define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment))) |
522 return align_size_up_(size, alignment) == size; |
522 |
523 } |
523 // Helpers to align sizes and check for alignment |
524 |
524 |
525 inline bool is_ptr_aligned(const void* ptr, size_t alignment) { |
525 template <typename T, typename A> |
526 return align_size_up_((intptr_t)ptr, (intptr_t)alignment) == (intptr_t)ptr; |
526 inline T align_size_up(T size, A alignment) { |
527 } |
|
528 |
|
529 inline intptr_t align_size_up(intptr_t size, intptr_t alignment) { |
|
530 return align_size_up_(size, alignment); |
527 return align_size_up_(size, alignment); |
531 } |
528 } |
532 |
529 |
533 inline intptr_t align_size_down(intptr_t size, intptr_t alignment) { |
530 template <typename T, typename A> |
|
531 inline T align_size_down(T size, A alignment) { |
534 return align_size_down_(size, alignment); |
532 return align_size_down_(size, alignment); |
535 } |
533 } |
536 |
534 |
537 #define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment))) |
535 template <typename T, typename A> |
538 |
536 inline bool is_size_aligned(T size, A alignment) { |
539 inline void* align_ptr_up(const void* ptr, size_t alignment) { |
537 return is_size_aligned_(size, alignment); |
540 return (void*)align_size_up((intptr_t)ptr, (intptr_t)alignment); |
538 } |
541 } |
539 |
542 |
540 // Align down with a lower bound. If the aligning results in 0, return 'alignment'. |
543 inline void* align_ptr_down(void* ptr, size_t alignment) { |
541 template <typename T, typename A> |
544 return (void*)align_size_down((intptr_t)ptr, (intptr_t)alignment); |
542 inline T align_size_down_bounded(T size, A alignment) { |
545 } |
543 A aligned_size = align_size_down(size, alignment); |
546 |
544 return aligned_size > 0 ? aligned_size : alignment; |
547 inline volatile void* align_ptr_down(volatile void* ptr, size_t alignment) { |
545 } |
548 return (volatile void*)align_size_down((intptr_t)ptr, (intptr_t)alignment); |
546 |
|
547 // Helpers to align pointers and check for alignment. |
|
548 |
|
549 template <typename T, typename A> |
|
550 inline T* align_ptr_up(T* ptr, A alignment) { |
|
551 return (T*)align_size_up((uintptr_t)ptr, alignment); |
|
552 } |
|
553 |
|
554 template <typename T, typename A> |
|
555 inline T* align_ptr_down(T* ptr, A alignment) { |
|
556 return (T*)align_size_down((uintptr_t)ptr, alignment); |
|
557 } |
|
558 |
|
559 template <typename T, typename A> |
|
560 inline bool is_ptr_aligned(T* ptr, A alignment) { |
|
561 return is_size_aligned((uintptr_t)ptr, alignment); |
549 } |
562 } |
550 |
563 |
551 // Align metaspace objects by rounding up to natural word boundary |
564 // Align metaspace objects by rounding up to natural word boundary |
552 |
565 template <typename T> |
553 inline intptr_t align_metadata_size(intptr_t size) { |
566 inline T align_metadata_size(T size) { |
554 return align_size_up(size, 1); |
567 return align_size_up(size, 1); |
555 } |
568 } |
556 |
569 |
557 // Align objects in the Java Heap by rounding up their size, in HeapWord units. |
570 // Align objects in the Java Heap by rounding up their size, in HeapWord units. |
558 // Since the size is given in words this is somewhat of a nop, but |
571 template <typename T> |
559 // distinguishes it from align_object_size. |
572 inline T align_object_size(T word_size) { |
560 inline intptr_t align_object_size(intptr_t size) { |
573 return align_size_up(word_size, MinObjAlignment); |
561 return align_size_up(size, MinObjAlignment); |
574 } |
562 } |
575 |
563 |
576 inline bool is_object_aligned(size_t word_size) { |
564 inline bool is_object_aligned(intptr_t addr) { |
577 return is_size_aligned(word_size, MinObjAlignment); |
565 return addr == align_object_size(addr); |
|
566 } |
578 } |
567 |
579 |
568 inline bool is_ptr_object_aligned(const void* addr) { |
580 inline bool is_ptr_object_aligned(const void* addr) { |
569 return is_ptr_aligned(addr, MinObjAlignmentInBytes); |
581 return is_ptr_aligned(addr, MinObjAlignmentInBytes); |
570 } |
582 } |
571 |
583 |
572 // Pad out certain offsets to jlong alignment, in HeapWord units. |
584 // Pad out certain offsets to jlong alignment, in HeapWord units. |
573 |
585 template <typename T> |
574 inline intptr_t align_object_offset(intptr_t offset) { |
586 inline T align_object_offset(T offset) { |
575 return align_size_up(offset, HeapWordsPerLong); |
587 return align_size_up(offset, HeapWordsPerLong); |
576 } |
|
577 |
|
578 // Align down with a lower bound. If the aligning results in 0, return 'alignment'. |
|
579 |
|
580 inline size_t align_size_down_bounded(size_t size, size_t alignment) { |
|
581 size_t aligned_size = align_size_down_(size, alignment); |
|
582 return aligned_size > 0 ? aligned_size : alignment; |
|
583 } |
588 } |
584 |
589 |
585 // Clamp an address to be within a specific page |
590 // Clamp an address to be within a specific page |
586 // 1. If addr is on the page it is returned as is |
591 // 1. If addr is on the page it is returned as is |
587 // 2. If addr is above the page_address the start of the *next* page will be returned |
592 // 2. If addr is above the page_address the start of the *next* page will be returned |
588 // 3. Otherwise, if addr is below the page_address the start of the page will be returned |
593 // 3. Otherwise, if addr is below the page_address the start of the page will be returned |
589 inline address clamp_address_in_page(address addr, address page_address, intptr_t page_size) { |
594 template <typename T> |
590 if (align_size_down(intptr_t(addr), page_size) == align_size_down(intptr_t(page_address), page_size)) { |
595 inline T* clamp_address_in_page(T* addr, T* page_address, size_t page_size) { |
|
596 if (align_ptr_down(addr, page_size) == align_ptr_down(page_address, page_size)) { |
591 // address is in the specified page, just return it as is |
597 // address is in the specified page, just return it as is |
592 return addr; |
598 return addr; |
593 } else if (addr > page_address) { |
599 } else if (addr > page_address) { |
594 // address is above specified page, return start of next page |
600 // address is above specified page, return start of next page |
595 return (address)align_size_down(intptr_t(page_address), page_size) + page_size; |
601 return align_ptr_down(page_address, page_size) + page_size; |
596 } else { |
602 } else { |
597 // address is below specified page, return start of page |
603 // address is below specified page, return start of page |
598 return (address)align_size_down(intptr_t(page_address), page_size); |
604 return align_ptr_down(page_address, page_size); |
599 } |
605 } |
600 } |
606 } |
601 |
607 |
602 |
608 |
603 // The expected size in bytes of a cache line, used to pad data structures. |
609 // The expected size in bytes of a cache line, used to pad data structures. |