6464#include " services/nmtCommon.hpp"
6565#include " services/threadService.hpp"
6666#include " utilities/align.hpp"
67+ #include " utilities/count_trailing_zeros.hpp"
6768#include " utilities/defaultStream.hpp"
6869#include " utilities/events.hpp"
70+ #include " utilities/powerOfTwo.hpp"
6971
7072# include < signal.h>
7173# include < errno.h>
@@ -75,7 +77,7 @@ address os::_polling_page = NULL;
7577volatile unsigned int os::_rand_seed = 1234567 ;
7678int os::_processor_count = 0 ;
7779int os::_initial_active_processor_count = 0 ;
78- size_t os::_page_sizes[os::page_sizes_max] ;
80+ os::PageSizes os::_page_sizes;
7981
8082#ifndef PRODUCT
8183julong os::num_mallocs = 0 ; // # of calls to malloc/realloc
@@ -1390,8 +1392,8 @@ size_t os::page_size_for_region(size_t region_size, size_t min_pages, bool must_
13901392 if (UseLargePages) {
13911393 const size_t max_page_size = region_size / min_pages;
13921394
1393- for (size_t i = 0 ; _page_sizes[i] != 0 ; ++i) {
1394- const size_t page_size = _page_sizes[i];
1395+ for (size_t page_size = page_sizes (). largest (); page_size != 0 ;
1396+ page_size = page_sizes (). next_smaller (page_size)) {
13951397 if (page_size <= max_page_size) {
13961398 if (!must_be_aligned || is_aligned (region_size, page_size)) {
13971399 return page_size;
@@ -1536,19 +1538,6 @@ const char* os::errno_name(int e) {
15361538 return errno_to_string (e, true );
15371539}
15381540
1539- void os::trace_page_sizes (const char * str, const size_t * page_sizes, int count) {
1540- LogTarget (Info, pagesize) log;
1541- if (log.is_enabled ()) {
1542- LogStream out (log);
1543-
1544- out.print (" %s: " , str);
1545- for (int i = 0 ; i < count; ++i) {
1546- out.print (" " SIZE_FORMAT, page_sizes[i]);
1547- }
1548- out.cr ();
1549- }
1550- }
1551-
15521541#define trace_page_size_params (size ) byte_size_in_exact_unit(size), exact_unit_for_byte_size(size)
15531542
15541543void os::trace_page_sizes (const char * str,
@@ -1862,3 +1851,73 @@ void os::naked_sleep(jlong millis) {
18621851 }
18631852 naked_short_sleep (millis);
18641853}
1854+
1855+
1856+ // //// Implementation of PageSizes
1857+
1858+ void os::PageSizes::add (size_t page_size) {
1859+ assert (is_power_of_2 (page_size), " page_size must be a power of 2: " SIZE_FORMAT_HEX, page_size);
1860+ _v |= page_size;
1861+ }
1862+
1863+ bool os::PageSizes::contains (size_t page_size) const {
1864+ assert (is_power_of_2 (page_size), " page_size must be a power of 2: " SIZE_FORMAT_HEX, page_size);
1865+ return (_v & page_size) != 0 ;
1866+ }
1867+
1868+ size_t os::PageSizes::next_smaller (size_t page_size) const {
1869+ assert (is_power_of_2 (page_size), " page_size must be a power of 2: " SIZE_FORMAT_HEX, page_size);
1870+ size_t v2 = _v & (page_size - 1 );
1871+ if (v2 == 0 ) {
1872+ return 0 ;
1873+ }
1874+ return round_down_power_of_2 (v2);
1875+ }
1876+
1877+ size_t os::PageSizes::next_larger (size_t page_size) const {
1878+ assert (is_power_of_2 (page_size), " page_size must be a power of 2: " SIZE_FORMAT_HEX, page_size);
1879+ if (page_size == max_power_of_2<size_t >()) { // Shift by 32/64 would be UB
1880+ return 0 ;
1881+ }
1882+ // Remove current and smaller page sizes
1883+ size_t v2 = _v & ~(page_size + (page_size - 1 ));
1884+ if (v2 == 0 ) {
1885+ return 0 ;
1886+ }
1887+ return (size_t )1 << count_trailing_zeros (v2);
1888+ }
1889+
1890+ size_t os::PageSizes::largest () const {
1891+ const size_t max = max_power_of_2<size_t >();
1892+ if (contains (max)) {
1893+ return max;
1894+ }
1895+ return next_smaller (max);
1896+ }
1897+
1898+ size_t os::PageSizes::smallest () const {
1899+ // Strictly speaking the set should not contain sizes < os::vm_page_size().
1900+ // But this is not enforced.
1901+ return next_larger (1 );
1902+ }
1903+
1904+ void os::PageSizes::print_on (outputStream* st) const {
1905+ bool first = true ;
1906+ for (size_t sz = smallest (); sz != 0 ; sz = next_larger (sz)) {
1907+ if (first) {
1908+ first = false ;
1909+ } else {
1910+ st->print_raw (" , " );
1911+ }
1912+ if (sz < M) {
1913+ st->print (SIZE_FORMAT " k" , sz / K);
1914+ } else if (sz < G) {
1915+ st->print (SIZE_FORMAT " M" , sz / M);
1916+ } else {
1917+ st->print (SIZE_FORMAT " G" , sz / G);
1918+ }
1919+ }
1920+ if (first) {
1921+ st->print (" empty" );
1922+ }
1923+ }
0 commit comments