hotspot/src/share/vm/memory/heap.cpp
changeset 27420 04e6f914cce1
parent 26809 8d3de4de954d
child 28631 a56cae1b428d
child 28493 26cabf3261fa
equal deleted inserted replaced
27419:a934f24b4dcf 27420:04e6f914cce1
   169   _next_segment = 0;
   169   _next_segment = 0;
   170   mark_segmap_as_free(0, _number_of_committed_segments);
   170   mark_segmap_as_free(0, _number_of_committed_segments);
   171 }
   171 }
   172 
   172 
   173 
   173 
   174 void* CodeHeap::allocate(size_t instance_size, bool is_critical) {
   174 void* CodeHeap::allocate(size_t instance_size) {
   175   size_t number_of_segments = size_to_segments(instance_size + header_size());
   175   size_t number_of_segments = size_to_segments(instance_size + header_size());
   176   assert(segments_to_size(number_of_segments) >= sizeof(FreeBlock), "not enough room for FreeList");
   176   assert(segments_to_size(number_of_segments) >= sizeof(FreeBlock), "not enough room for FreeList");
   177 
   177 
   178   // First check if we can satisfy request from freelist
   178   // First check if we can satisfy request from freelist
   179   NOT_PRODUCT(verify());
   179   NOT_PRODUCT(verify());
   180   HeapBlock* block = search_freelist(number_of_segments, is_critical);
   180   HeapBlock* block = search_freelist(number_of_segments);
   181   NOT_PRODUCT(verify());
   181   NOT_PRODUCT(verify());
   182 
   182 
   183   if (block != NULL) {
   183   if (block != NULL) {
   184     assert(block->length() >= number_of_segments && block->length() < number_of_segments + CodeCacheMinBlockLength, "sanity check");
   184     assert(block->length() >= number_of_segments && block->length() < number_of_segments + CodeCacheMinBlockLength, "sanity check");
   185     assert(!block->free(), "must be marked free");
   185     assert(!block->free(), "must be marked free");
   188     return block->allocated_space();
   188     return block->allocated_space();
   189   }
   189   }
   190 
   190 
   191   // Ensure minimum size for allocation to the heap.
   191   // Ensure minimum size for allocation to the heap.
   192   number_of_segments = MAX2((int)CodeCacheMinBlockLength, (int)number_of_segments);
   192   number_of_segments = MAX2((int)CodeCacheMinBlockLength, (int)number_of_segments);
   193 
       
   194   if (!is_critical) {
       
   195     // Make sure the allocation fits in the unallocated heap without using
       
   196     // the CodeCacheMimimumFreeSpace that is reserved for critical allocations.
       
   197     if (segments_to_size(number_of_segments) > (heap_unallocated_capacity() - CodeCacheMinimumFreeSpace)) {
       
   198       // Fail allocation
       
   199       return NULL;
       
   200     }
       
   201   }
       
   202 
   193 
   203   if (_next_segment + number_of_segments <= _number_of_committed_segments) {
   194   if (_next_segment + number_of_segments <= _number_of_committed_segments) {
   204     mark_segmap_as_used(_next_segment, _next_segment + number_of_segments);
   195     mark_segmap_as_used(_next_segment, _next_segment + number_of_segments);
   205     HeapBlock* b =  block_at(_next_segment);
   196     HeapBlock* b =  block_at(_next_segment);
   206     b->initialize(number_of_segments);
   197     b->initialize(number_of_segments);
   425 
   416 
   426 /**
   417 /**
   427  * Search freelist for an entry on the list with the best fit.
   418  * Search freelist for an entry on the list with the best fit.
   428  * @return NULL, if no one was found
   419  * @return NULL, if no one was found
   429  */
   420  */
   430 FreeBlock* CodeHeap::search_freelist(size_t length, bool is_critical) {
   421 FreeBlock* CodeHeap::search_freelist(size_t length) {
   431   FreeBlock* found_block = NULL;
   422   FreeBlock* found_block = NULL;
   432   FreeBlock* found_prev  = NULL;
   423   FreeBlock* found_prev  = NULL;
   433   size_t     found_length = 0;
   424   size_t     found_length = 0;
   434 
   425 
   435   FreeBlock* prev = NULL;
   426   FreeBlock* prev = NULL;
   436   FreeBlock* cur = _freelist;
   427   FreeBlock* cur = _freelist;
   437   const size_t critical_boundary = (size_t)high_boundary() - CodeCacheMinimumFreeSpace;
       
   438 
   428 
   439   // Search for first block that fits
   429   // Search for first block that fits
   440   while(cur != NULL) {
   430   while(cur != NULL) {
   441     if (cur->length() >= length) {
   431     if (cur->length() >= length) {
   442       // Non critical allocations are not allowed to use the last part of the code heap.
       
   443       // Make sure the end of the allocation doesn't cross into the last part of the code heap.
       
   444       if (!is_critical && (((size_t)cur + length) > critical_boundary)) {
       
   445         // The freelist is sorted by address - if one fails, all consecutive will also fail.
       
   446         break;
       
   447       }
       
   448       // Remember block, its previous element, and its length
   432       // Remember block, its previous element, and its length
   449       found_block = cur;
   433       found_block = cur;
   450       found_prev  = prev;
   434       found_prev  = prev;
   451       found_length = found_block->length();
   435       found_length = found_block->length();
   452 
   436