< prev index next >

src/share/vm/runtime/os.cpp

Print this page
rev 7180 : 8067469: G1 ignores AlwaysPreTouch
Summary: Factor out pretouch code of the various virtual space management classes and use them everywhere including in G1.
Reviewed-by: stefank, ehelin, dholmes
rev 7181 : 8049864: TestParallelHeapSizeFlags fails with unexpected heap size
Reviewed-by: sjohanss, jmasa

@@ -1313,28 +1313,19 @@
   // The very lower end of the stack
   address stack_limit = thread->stack_base() - thread->stack_size();
   return (sp > (stack_limit + reserved_area));
 }
 
-size_t os::page_size_for_region(size_t region_min_size, size_t region_max_size,
-                                uint min_pages)
-{
+size_t os::page_size_for_region(size_t region_size, size_t min_pages) {
   assert(min_pages > 0, "sanity");
   if (UseLargePages) {
-    const size_t max_page_size = region_max_size / min_pages;
-
-    for (unsigned int i = 0; _page_sizes[i] != 0; ++i) {
-      const size_t sz = _page_sizes[i];
-      const size_t mask = sz - 1;
-      if ((region_min_size & mask) == 0 && (region_max_size & mask) == 0) {
-        // The largest page size with no fragmentation.
-        return sz;
-      }
+    const size_t max_page_size = region_size / min_pages;
 
-      if (sz <= max_page_size) {
-        // The largest page size that satisfies the min_pages requirement.
-        return sz;
+    for (size_t i = 0; _page_sizes[i] != 0; ++i) {
+      const size_t page_size = _page_sizes[i];
+      if (page_size <= max_page_size && is_size_aligned(region_size, page_size)) {
+        return page_size;
       }
     }
   }
 
   return vm_page_size();

@@ -1572,5 +1563,65 @@
     return to;
   }
   return result;
 }
 #endif
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+#define assert_eq(a,b) assert(a == b, err_msg(SIZE_FORMAT " != " SIZE_FORMAT, a, b))
+
+class TestOS : AllStatic {
+  static size_t small_page_size() {
+    return os::vm_page_size();
+  }
+
+  static size_t large_page_size() {
+    const size_t large_page_size_example = 4 * M;
+    return os::page_size_for_region(large_page_size_example, 1);
+  }
+
+  static void test_page_size_for_region() {
+    if (UseLargePages) {
+      const size_t small_page = small_page_size();
+      const size_t large_page = large_page_size();
+
+      if (large_page > small_page) {
+        size_t num_small_pages_in_large = large_page / small_page;
+        size_t page = os::page_size_for_region(large_page, num_small_pages_in_large);
+
+        assert_eq(page, small_page);
+      }
+    }
+  }
+
+  static void test_page_size_for_region_alignment() {
+    if (UseLargePages) {
+      const size_t small_page = small_page_size();
+      const size_t large_page = large_page_size();
+      if (large_page > small_page) {
+        const size_t unaligned_region = large_page + 17;
+        size_t page = os::page_size_for_region(unaligned_region, 1);
+        assert_eq(page, small_page);
+
+        const size_t num_pages = 5;
+        const size_t aligned_region = large_page * num_pages;
+        page = os::page_size_for_region(aligned_region, num_pages);
+        assert_eq(page, large_page);
+      }
+    }
+  }
+
+ public:
+  static void run_tests() {
+    test_page_size_for_region();
+    test_page_size_for_region_alignment();
+  }
+};
+
+void TestOS_test() {
+  TestOS::run_tests();
+}
+
+#endif // PRODUCT
< prev index next >