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;
|