< prev index next >

src/hotspot/os/linux/os_linux.cpp

Print this page




3101   }
3102 
3103   return nbot;
3104 }
3105 
3106 bool os::committed_in_range(address start, size_t size, address& committed_start, size_t& committed_size) {
3107   int mincore_return_value;
3108   const size_t stripe = 1024;  // query this many pages each time
3109   unsigned char vec[stripe];
3110   const size_t page_sz = os::vm_page_size();
3111   size_t pages = size / page_sz;
3112 
3113   assert(is_aligned(start, page_sz), "Start address must be page aligned");
3114   assert(is_aligned(size, page_sz), "Size must be page aligned");
3115 
3116   committed_start = NULL;
3117 
3118   int loops = (pages + stripe - 1) / stripe;
3119   int committed_pages = 0;
3120   address loop_base = start;
3121   for (int index = 0; index < loops; index ++) {


3122     assert(pages > 0, "Nothing to do");
3123     int pages_to_query = (pages >= stripe) ? stripe : pages;
3124     pages -= pages_to_query;
3125 
3126     // Get stable read
3127     while ((mincore_return_value = mincore(loop_base, pages_to_query * page_sz, vec)) == -1 && errno == EAGAIN);
3128 
3129     // During shutdown, some memory goes away without properly notifying NMT,
3130     // E.g. ConcurrentGCThread/WatcherThread can exit without deleting thread object.
3131     // Bailout and return as not committed for now.
3132     if (mincore_return_value == -1 && errno == ENOMEM) {
3133       return false;
3134     }
3135 
3136     assert(mincore_return_value == 0, "Range must be valid");
3137     // Process this stripe
3138     for (int vecIdx = 0; vecIdx < pages_to_query; vecIdx ++) {
3139       if ((vec[vecIdx] & 0x01) == 0) { // not committed
3140         // End of current contiguous region
3141         if (committed_start != NULL) {

3142           break;
3143         }
3144       } else { // committed
3145         // Start of region
3146         if (committed_start == NULL) {
3147           committed_start = loop_base + page_sz * vecIdx;
3148         }
3149         committed_pages ++;
3150       }
3151     }
3152 
3153     loop_base += pages_to_query * page_sz;
3154   }
3155 
3156   if (committed_start != NULL) {
3157     assert(committed_pages > 0, "Must have committed region");
3158     assert(committed_pages <= int(size / page_sz), "Can not commit more than it has");
3159     assert(committed_start >= start && committed_start < start + size, "Out of range");
3160     committed_size = page_sz * committed_pages;
3161     return true;




3101   }
3102 
3103   return nbot;
3104 }
3105 
3106 bool os::committed_in_range(address start, size_t size, address& committed_start, size_t& committed_size) {
3107   int mincore_return_value;
3108   const size_t stripe = 1024;  // query this many pages each time
3109   unsigned char vec[stripe];
3110   const size_t page_sz = os::vm_page_size();
3111   size_t pages = size / page_sz;
3112 
3113   assert(is_aligned(start, page_sz), "Start address must be page aligned");
3114   assert(is_aligned(size, page_sz), "Size must be page aligned");
3115 
3116   committed_start = NULL;
3117 
3118   int loops = (pages + stripe - 1) / stripe;
3119   int committed_pages = 0;
3120   address loop_base = start;
3121   bool found_range = false;
3122 
3123   for (int index = 0; index < loops && !found_range; index ++) {
3124     assert(pages > 0, "Nothing to do");
3125     int pages_to_query = (pages >= stripe) ? stripe : pages;
3126     pages -= pages_to_query;
3127 
3128     // Get stable read
3129     while ((mincore_return_value = mincore(loop_base, pages_to_query * page_sz, vec)) == -1 && errno == EAGAIN);
3130 
3131     // During shutdown, some memory goes away without properly notifying NMT,
3132     // E.g. ConcurrentGCThread/WatcherThread can exit without deleting thread object.
3133     // Bailout and return as not committed for now.
3134     if (mincore_return_value == -1 && errno == ENOMEM) {
3135       return false;
3136     }
3137 
3138     assert(mincore_return_value == 0, "Range must be valid");
3139     // Process this stripe
3140     for (int vecIdx = 0; vecIdx < pages_to_query; vecIdx ++) {
3141       if ((vec[vecIdx] & 0x01) == 0) { // not committed
3142         // End of current contiguous region
3143         if (committed_start != NULL) {
3144           found_range = true;
3145           break;
3146         }
3147       } else { // committed
3148         // Start of region
3149         if (committed_start == NULL) {
3150           committed_start = loop_base + page_sz * vecIdx;
3151         }
3152         committed_pages ++;
3153       }
3154     }
3155 
3156     loop_base += pages_to_query * page_sz;
3157   }
3158 
3159   if (committed_start != NULL) {
3160     assert(committed_pages > 0, "Must have committed region");
3161     assert(committed_pages <= int(size / page_sz), "Can not commit more than it has");
3162     assert(committed_start >= start && committed_start < start + size, "Out of range");
3163     committed_size = page_sz * committed_pages;
3164     return true;


< prev index next >