< prev index next >

src/share/vm/memory/metaspace.cpp

Print this page




3457   }
3458 
3459   assert(loader_data != NULL, "Should never pass around a NULL loader_data. "
3460         "ClassLoaderData::the_null_class_loader_data() should have been used.");
3461 
3462   // Allocate in metaspaces without taking out a lock, because it deadlocks
3463   // with the SymbolTable_lock.  Dumping is single threaded for now.  We'll have
3464   // to revisit this for application class data sharing.
3465   if (DumpSharedSpaces) {
3466     assert(type > MetaspaceObj::UnknownType && type < MetaspaceObj::_number_of_types, "sanity");
3467     Metaspace* space = read_only ? loader_data->ro_metaspace() : loader_data->rw_metaspace();
3468     MetaWord* result = space->allocate(word_size, NonClassType);
3469     if (result == NULL) {
3470       report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite);
3471     }
3472     if (PrintSharedSpaces) {
3473       space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size));
3474     }
3475 
3476     // Zero initialize.
3477     Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0);
3478 
3479     return result;
3480   }
3481 
3482   MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType;
3483 
3484   // Try to allocate metadata.
3485   MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
3486 
3487   if (result == NULL) {
3488     tracer()->report_metaspace_allocation_failure(loader_data, word_size, type, mdtype);
3489 
3490     // Allocation failed.
3491     if (is_init_completed()) {
3492       // Only start a GC if the bootstrapping has completed.
3493 
3494       // Try to clean out some memory and retry.
3495       result = Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation(
3496           loader_data, word_size, mdtype);
3497     }
3498   }
3499 
3500   if (result == NULL) {
3501     SpaceManager* sm;
3502     if (is_class_space_allocation(mdtype)) {
3503       sm = loader_data->metaspace_non_null()->class_vsm();
3504     } else {
3505       sm = loader_data->metaspace_non_null()->vsm();
3506     }
3507 
3508     result = sm->get_small_chunk_and_allocate(word_size);
3509 
3510     if (result == NULL) {
3511       report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL);
3512     }
3513   }
3514 
3515   // Zero initialize.
3516   Copy::fill_to_aligned_words((HeapWord*)result, word_size, 0);
3517 
3518   return result;
3519 }
3520 
3521 size_t Metaspace::class_chunk_size(size_t word_size) {
3522   assert(using_class_space(), "Has to use class space");
3523   return class_vsm()->calc_chunk_size(word_size);
3524 }
3525 
3526 void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_size, MetaspaceObj::Type type, MetadataType mdtype, TRAPS) {
3527   tracer()->report_metadata_oom(loader_data, word_size, type, mdtype);
3528 
3529   // If result is still null, we are out of memory.
3530   LogHandle(gc, metaspace, freelist) log;
3531   if (log.is_trace()) {
3532     log.trace("Metaspace allocation failed for size " SIZE_FORMAT, word_size);
3533     ResourceMark rm;
3534     outputStream* out = log.trace_stream();
3535     if (loader_data->metaspace_or_null() != NULL) {
3536       loader_data->dump(out);


3566   if (out_of_compressed_class_space) {
3567     THROW_OOP(Universe::out_of_memory_error_class_metaspace());
3568   } else {
3569     THROW_OOP(Universe::out_of_memory_error_metaspace());
3570   }
3571 }
3572 
3573 const char* Metaspace::metadata_type_name(Metaspace::MetadataType mdtype) {
3574   switch (mdtype) {
3575     case Metaspace::ClassType: return "Class";
3576     case Metaspace::NonClassType: return "Metadata";
3577     default:
3578       assert(false, "Got bad mdtype: %d", (int) mdtype);
3579       return NULL;
3580   }
3581 }
3582 
3583 void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) {
3584   assert(DumpSharedSpaces, "sanity");
3585 
3586   int byte_size = (int)word_size * HeapWordSize;
3587   AllocRecord *rec = new AllocRecord((address)ptr, type, byte_size);
3588 
3589   if (_alloc_record_head == NULL) {
3590     _alloc_record_head = _alloc_record_tail = rec;
3591   } else if (_alloc_record_tail->_ptr + _alloc_record_tail->_byte_size == (address)ptr) {
3592     _alloc_record_tail->_next = rec;
3593     _alloc_record_tail = rec;
3594   } else {
3595     // slow linear search, but this doesn't happen that often, and only when dumping
3596     for (AllocRecord *old = _alloc_record_head; old; old = old->_next) {
3597       if (old->_ptr == ptr) {
3598         assert(old->_type == MetaspaceObj::DeallocatedType, "sanity");
3599         int remain_bytes = old->_byte_size - byte_size;
3600         assert(remain_bytes >= 0, "sanity");
3601         old->_type = type;
3602 
3603         if (remain_bytes == 0) {
3604           delete(rec);
3605         } else {
3606           address remain_ptr = address(ptr) + byte_size;
3607           rec->_ptr = remain_ptr;
3608           rec->_byte_size = remain_bytes;
3609           rec->_type = MetaspaceObj::DeallocatedType;
3610           rec->_next = old->_next;
3611           old->_byte_size = byte_size;
3612           old->_next = rec;
3613         }
3614         return;
3615       }
3616     }
3617     assert(0, "reallocating a freed pointer that was not recorded");
3618   }
3619 }
3620 
3621 void Metaspace::record_deallocation(void* ptr, size_t word_size) {
3622   assert(DumpSharedSpaces, "sanity");
3623 
3624   for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) {
3625     if (rec->_ptr == ptr) {
3626       assert(rec->_byte_size == (int)word_size * HeapWordSize, "sanity");
3627       rec->_type = MetaspaceObj::DeallocatedType;
3628       return;
3629     }
3630   }
3631 
3632   assert(0, "deallocating a pointer that was not recorded");
3633 }
3634 
3635 void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) {
3636   assert(DumpSharedSpaces, "unimplemented for !DumpSharedSpaces");
3637 
3638   address last_addr = (address)bottom();
3639 
3640   for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) {
3641     address ptr = rec->_ptr;
3642     if (last_addr < ptr) {
3643       closure->doit(last_addr, MetaspaceObj::UnknownType, ptr - last_addr);
3644     }
3645     closure->doit(ptr, rec->_type, rec->_byte_size);
3646     last_addr = ptr + rec->_byte_size;




3457   }
3458 
3459   assert(loader_data != NULL, "Should never pass around a NULL loader_data. "
3460         "ClassLoaderData::the_null_class_loader_data() should have been used.");
3461 
3462   // Allocate in metaspaces without taking out a lock, because it deadlocks
3463   // with the SymbolTable_lock.  Dumping is single threaded for now.  We'll have
3464   // to revisit this for application class data sharing.
3465   if (DumpSharedSpaces) {
3466     assert(type > MetaspaceObj::UnknownType && type < MetaspaceObj::_number_of_types, "sanity");
3467     Metaspace* space = read_only ? loader_data->ro_metaspace() : loader_data->rw_metaspace();
3468     MetaWord* result = space->allocate(word_size, NonClassType);
3469     if (result == NULL) {
3470       report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite);
3471     }
3472     if (PrintSharedSpaces) {
3473       space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size));
3474     }
3475 
3476     // Zero initialize.
3477     Copy::fill_to_words((HeapWord*)result, word_size, 0);
3478 
3479     return result;
3480   }
3481 
3482   MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType;
3483 
3484   // Try to allocate metadata.
3485   MetaWord* result = loader_data->metaspace_non_null()->allocate(word_size, mdtype);
3486 
3487   if (result == NULL) {
3488     tracer()->report_metaspace_allocation_failure(loader_data, word_size, type, mdtype);
3489 
3490     // Allocation failed.
3491     if (is_init_completed()) {
3492       // Only start a GC if the bootstrapping has completed.
3493 
3494       // Try to clean out some memory and retry.
3495       result = Universe::heap()->collector_policy()->satisfy_failed_metadata_allocation(
3496           loader_data, word_size, mdtype);
3497     }
3498   }
3499 
3500   if (result == NULL) {
3501     SpaceManager* sm;
3502     if (is_class_space_allocation(mdtype)) {
3503       sm = loader_data->metaspace_non_null()->class_vsm();
3504     } else {
3505       sm = loader_data->metaspace_non_null()->vsm();
3506     }
3507 
3508     result = sm->get_small_chunk_and_allocate(word_size);
3509 
3510     if (result == NULL) {
3511       report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL);
3512     }
3513   }
3514 
3515   // Zero initialize.
3516   Copy::fill_to_words((HeapWord*)result, word_size, 0);
3517 
3518   return result;
3519 }
3520 
3521 size_t Metaspace::class_chunk_size(size_t word_size) {
3522   assert(using_class_space(), "Has to use class space");
3523   return class_vsm()->calc_chunk_size(word_size);
3524 }
3525 
3526 void Metaspace::report_metadata_oome(ClassLoaderData* loader_data, size_t word_size, MetaspaceObj::Type type, MetadataType mdtype, TRAPS) {
3527   tracer()->report_metadata_oom(loader_data, word_size, type, mdtype);
3528 
3529   // If result is still null, we are out of memory.
3530   LogHandle(gc, metaspace, freelist) log;
3531   if (log.is_trace()) {
3532     log.trace("Metaspace allocation failed for size " SIZE_FORMAT, word_size);
3533     ResourceMark rm;
3534     outputStream* out = log.trace_stream();
3535     if (loader_data->metaspace_or_null() != NULL) {
3536       loader_data->dump(out);


3566   if (out_of_compressed_class_space) {
3567     THROW_OOP(Universe::out_of_memory_error_class_metaspace());
3568   } else {
3569     THROW_OOP(Universe::out_of_memory_error_metaspace());
3570   }
3571 }
3572 
3573 const char* Metaspace::metadata_type_name(Metaspace::MetadataType mdtype) {
3574   switch (mdtype) {
3575     case Metaspace::ClassType: return "Class";
3576     case Metaspace::NonClassType: return "Metadata";
3577     default:
3578       assert(false, "Got bad mdtype: %d", (int) mdtype);
3579       return NULL;
3580   }
3581 }
3582 
3583 void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) {
3584   assert(DumpSharedSpaces, "sanity");
3585 
3586   int byte_size = (int)word_size * wordSize;
3587   AllocRecord *rec = new AllocRecord((address)ptr, type, byte_size);
3588 
3589   if (_alloc_record_head == NULL) {
3590     _alloc_record_head = _alloc_record_tail = rec;
3591   } else if (_alloc_record_tail->_ptr + _alloc_record_tail->_byte_size == (address)ptr) {
3592     _alloc_record_tail->_next = rec;
3593     _alloc_record_tail = rec;
3594   } else {
3595     // slow linear search, but this doesn't happen that often, and only when dumping
3596     for (AllocRecord *old = _alloc_record_head; old; old = old->_next) {
3597       if (old->_ptr == ptr) {
3598         assert(old->_type == MetaspaceObj::DeallocatedType, "sanity");
3599         int remain_bytes = old->_byte_size - byte_size;
3600         assert(remain_bytes >= 0, "sanity");
3601         old->_type = type;
3602 
3603         if (remain_bytes == 0) {
3604           delete(rec);
3605         } else {
3606           address remain_ptr = address(ptr) + byte_size;
3607           rec->_ptr = remain_ptr;
3608           rec->_byte_size = remain_bytes;
3609           rec->_type = MetaspaceObj::DeallocatedType;
3610           rec->_next = old->_next;
3611           old->_byte_size = byte_size;
3612           old->_next = rec;
3613         }
3614         return;
3615       }
3616     }
3617     assert(0, "reallocating a freed pointer that was not recorded");
3618   }
3619 }
3620 
3621 void Metaspace::record_deallocation(void* ptr, size_t word_size) {
3622   assert(DumpSharedSpaces, "sanity");
3623 
3624   for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) {
3625     if (rec->_ptr == ptr) {
3626       assert(rec->_byte_size == (int)word_size * wordSize, "sanity");
3627       rec->_type = MetaspaceObj::DeallocatedType;
3628       return;
3629     }
3630   }
3631 
3632   assert(0, "deallocating a pointer that was not recorded");
3633 }
3634 
3635 void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) {
3636   assert(DumpSharedSpaces, "unimplemented for !DumpSharedSpaces");
3637 
3638   address last_addr = (address)bottom();
3639 
3640   for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) {
3641     address ptr = rec->_ptr;
3642     if (last_addr < ptr) {
3643       closure->doit(last_addr, MetaspaceObj::UnknownType, ptr - last_addr);
3644     }
3645     closure->doit(ptr, rec->_type, rec->_byte_size);
3646     last_addr = ptr + rec->_byte_size;


< prev index next >