512 // this problem. |
512 // this problem. |
513 #define align_mask(alignment) ((alignment) - 1) |
513 #define align_mask(alignment) ((alignment) - 1) |
514 #define widen_to_type_of(what, type_carrier) (true ? (what) : (type_carrier)) |
514 #define widen_to_type_of(what, type_carrier) (true ? (what) : (type_carrier)) |
515 #define align_mask_widened(alignment, type_carrier) widen_to_type_of(align_mask(alignment), (type_carrier)) |
515 #define align_mask_widened(alignment, type_carrier) widen_to_type_of(align_mask(alignment), (type_carrier)) |
516 |
516 |
517 #define align_size_down_(size, alignment) ((size) & ~align_mask_widened((alignment), (size))) |
517 #define align_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_up_(size, alignment) (align_down_((size) + align_mask(alignment), (alignment))) |
520 |
520 |
521 #define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment))) |
521 #define is_aligned_(size, alignment) ((size) == (align_up_(size, alignment))) |
522 |
522 |
523 // Helpers to align sizes and check for alignment |
523 // Helpers to align sizes and check for alignment |
524 |
524 |
525 template <typename T, typename A> |
525 template <typename T, typename A> |
526 inline T align_size_up(T size, A alignment) { |
526 inline T align_up(T size, A alignment) { |
527 return align_size_up_(size, alignment); |
527 return align_up_(size, alignment); |
528 } |
528 } |
529 |
529 |
530 template <typename T, typename A> |
530 template <typename T, typename A> |
531 inline T align_size_down(T size, A alignment) { |
531 inline T align_down(T size, A alignment) { |
532 return align_size_down_(size, alignment); |
532 return align_down_(size, alignment); |
533 } |
533 } |
534 |
534 |
535 template <typename T, typename A> |
535 template <typename T, typename A> |
536 inline bool is_size_aligned(T size, A alignment) { |
536 inline bool is_aligned(T size, A alignment) { |
537 return is_size_aligned_(size, alignment); |
537 return is_aligned_(size, alignment); |
538 } |
538 } |
539 |
539 |
540 // Align down with a lower bound. If the aligning results in 0, return 'alignment'. |
540 // Align down with a lower bound. If the aligning results in 0, return 'alignment'. |
541 template <typename T, typename A> |
541 template <typename T, typename A> |
542 inline T align_size_down_bounded(T size, A alignment) { |
542 inline T align_down_bounded(T size, A alignment) { |
543 A aligned_size = align_size_down(size, alignment); |
543 A aligned_size = align_down(size, alignment); |
544 return aligned_size > 0 ? aligned_size : alignment; |
544 return aligned_size > 0 ? aligned_size : alignment; |
545 } |
545 } |
546 |
546 |
547 // Helpers to align pointers and check for alignment. |
547 // Helpers to align pointers and check for alignment. |
548 |
548 |
549 template <typename T, typename A> |
549 template <typename T, typename A> |
550 inline T* align_ptr_up(T* ptr, A alignment) { |
550 inline T* align_up(T* ptr, A alignment) { |
551 return (T*)align_size_up((uintptr_t)ptr, alignment); |
551 return (T*)align_up((uintptr_t)ptr, alignment); |
552 } |
552 } |
553 |
553 |
554 template <typename T, typename A> |
554 template <typename T, typename A> |
555 inline T* align_ptr_down(T* ptr, A alignment) { |
555 inline T* align_down(T* ptr, A alignment) { |
556 return (T*)align_size_down((uintptr_t)ptr, alignment); |
556 return (T*)align_down((uintptr_t)ptr, alignment); |
557 } |
557 } |
558 |
558 |
559 template <typename T, typename A> |
559 template <typename T, typename A> |
560 inline bool is_ptr_aligned(T* ptr, A alignment) { |
560 inline bool is_aligned(T* ptr, A alignment) { |
561 return is_size_aligned((uintptr_t)ptr, alignment); |
561 return is_aligned((uintptr_t)ptr, alignment); |
562 } |
562 } |
563 |
563 |
564 // Align metaspace objects by rounding up to natural word boundary |
564 // Align metaspace objects by rounding up to natural word boundary |
565 template <typename T> |
565 template <typename T> |
566 inline T align_metadata_size(T size) { |
566 inline T align_metadata_size(T size) { |
567 return align_size_up(size, 1); |
567 return align_up(size, 1); |
568 } |
568 } |
569 |
569 |
570 // 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. |
571 template <typename T> |
571 template <typename T> |
572 inline T align_object_size(T word_size) { |
572 inline T align_object_size(T word_size) { |
573 return align_size_up(word_size, MinObjAlignment); |
573 return align_up(word_size, MinObjAlignment); |
574 } |
574 } |
575 |
575 |
576 inline bool is_object_aligned(size_t word_size) { |
576 inline bool is_object_aligned(size_t word_size) { |
577 return is_size_aligned(word_size, MinObjAlignment); |
577 return is_aligned(word_size, MinObjAlignment); |
578 } |
578 } |
579 |
579 |
580 inline bool is_ptr_object_aligned(const void* addr) { |
580 inline bool is_object_aligned(const void* addr) { |
581 return is_ptr_aligned(addr, MinObjAlignmentInBytes); |
581 return is_aligned(addr, MinObjAlignmentInBytes); |
582 } |
582 } |
583 |
583 |
584 // Pad out certain offsets to jlong alignment, in HeapWord units. |
584 // Pad out certain offsets to jlong alignment, in HeapWord units. |
585 template <typename T> |
585 template <typename T> |
586 inline T align_object_offset(T offset) { |
586 inline T align_object_offset(T offset) { |
587 return align_size_up(offset, HeapWordsPerLong); |
587 return align_up(offset, HeapWordsPerLong); |
588 } |
588 } |
589 |
589 |
590 // Clamp an address to be within a specific page |
590 // Clamp an address to be within a specific page |
591 // 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 |
592 // 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 |
593 // 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 |
594 template <typename T> |
594 template <typename T> |
595 inline T* clamp_address_in_page(T* addr, T* page_address, size_t 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)) { |
596 if (align_down(addr, page_size) == align_down(page_address, page_size)) { |
597 // address is in the specified page, just return it as is |
597 // address is in the specified page, just return it as is |
598 return addr; |
598 return addr; |
599 } else if (addr > page_address) { |
599 } else if (addr > page_address) { |
600 // address is above specified page, return start of next page |
600 // address is above specified page, return start of next page |
601 return align_ptr_down(page_address, page_size) + page_size; |
601 return align_down(page_address, page_size) + page_size; |
602 } else { |
602 } else { |
603 // address is below specified page, return start of page |
603 // address is below specified page, return start of page |
604 return align_ptr_down(page_address, page_size); |
604 return align_down(page_address, page_size); |
605 } |
605 } |
606 } |
606 } |
607 |
607 |
608 |
608 |
609 // 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. |