hotspot/src/share/vm/gc/g1/g1CodeCacheRemSet.cpp
changeset 35879 9892f53e92c9
parent 33105 294e48b4f704
child 40905 94ffc131534f
equal deleted inserted replaced
35874:6c93eabea7c2 35879:9892f53e92c9
     1 /*
     1 /*
     2  * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    72   static void purge();
    72   static void purge();
    73 
    73 
    74   static size_t static_mem_size() {
    74   static size_t static_mem_size() {
    75     return sizeof(_purge_list);
    75     return sizeof(_purge_list);
    76   }
    76   }
       
    77 
       
    78   size_t mem_size();
    77 };
    79 };
    78 
    80 
    79 CodeRootSetTable* volatile CodeRootSetTable::_purge_list = NULL;
    81 CodeRootSetTable* volatile CodeRootSetTable::_purge_list = NULL;
       
    82 
       
    83 size_t CodeRootSetTable::mem_size() {
       
    84   return sizeof(CodeRootSetTable) + (entry_size() * number_of_entries()) + (sizeof(HashtableBucket<mtGC>) * table_size());
       
    85 }
    80 
    86 
    81 CodeRootSetTable::Entry* CodeRootSetTable::new_entry(nmethod* nm) {
    87 CodeRootSetTable::Entry* CodeRootSetTable::new_entry(nmethod* nm) {
    82   unsigned int hash = compute_hash(nm);
    88   unsigned int hash = compute_hash(nm);
    83   Entry* entry = (Entry*) new_entry_free_list();
    89   Entry* entry = (Entry*) new_entry_free_list();
    84   if (entry == NULL) {
    90   if (entry == NULL) {
   230   CodeRootSetTable::purge_list_append(_table);
   236   CodeRootSetTable::purge_list_append(_table);
   231 
   237 
   232   OrderAccess::release_store_ptr(&_table, temp);
   238   OrderAccess::release_store_ptr(&_table, temp);
   233 }
   239 }
   234 
   240 
   235 
       
   236 void G1CodeRootSet::purge() {
   241 void G1CodeRootSet::purge() {
   237   CodeRootSetTable::purge();
   242   CodeRootSetTable::purge();
   238 }
   243 }
   239 
   244 
   240 size_t G1CodeRootSet::static_mem_size() {
   245 size_t G1CodeRootSet::static_mem_size() {
   245   bool added = false;
   250   bool added = false;
   246   if (is_empty()) {
   251   if (is_empty()) {
   247     allocate_small_table();
   252     allocate_small_table();
   248   }
   253   }
   249   added = _table->add(method);
   254   added = _table->add(method);
   250   if (_length == Threshold) {
       
   251     move_to_large();
       
   252   }
       
   253   if (added) {
   255   if (added) {
       
   256     if (_length == Threshold) {
       
   257       move_to_large();
       
   258     }
   254     ++_length;
   259     ++_length;
   255   }
   260   }
       
   261   assert(_length == (size_t)_table->number_of_entries(), "sizes should match");
   256 }
   262 }
   257 
   263 
   258 bool G1CodeRootSet::remove(nmethod* method) {
   264 bool G1CodeRootSet::remove(nmethod* method) {
   259   bool removed = false;
   265   bool removed = false;
   260   if (_table != NULL) {
   266   if (_table != NULL) {
   264     _length--;
   270     _length--;
   265     if (_length == 0) {
   271     if (_length == 0) {
   266       clear();
   272       clear();
   267     }
   273     }
   268   }
   274   }
       
   275   assert((_length == 0 && _table == NULL) ||
       
   276          (_length == (size_t)_table->number_of_entries()), "sizes should match");
   269   return removed;
   277   return removed;
   270 }
   278 }
   271 
   279 
   272 bool G1CodeRootSet::contains(nmethod* method) {
   280 bool G1CodeRootSet::contains(nmethod* method) {
   273   CodeRootSetTable* table = load_acquire_table();
   281   CodeRootSetTable* table = load_acquire_table(); // contains() may be called outside of lock, so ensure mem sync.
   274   if (table != NULL) {
   282   if (table != NULL) {
   275     return table->contains(method);
   283     return table->contains(method);
   276   }
   284   }
   277   return false;
   285   return false;
   278 }
   286 }
   282   _table = NULL;
   290   _table = NULL;
   283   _length = 0;
   291   _length = 0;
   284 }
   292 }
   285 
   293 
   286 size_t G1CodeRootSet::mem_size() {
   294 size_t G1CodeRootSet::mem_size() {
   287   return sizeof(*this) +
   295   return sizeof(*this) + (_table != NULL ? _table->mem_size() : 0);
   288       (_table != NULL ? sizeof(CodeRootSetTable) + _table->entry_size() * _length : 0);
       
   289 }
   296 }
   290 
   297 
   291 void G1CodeRootSet::nmethods_do(CodeBlobClosure* blk) const {
   298 void G1CodeRootSet::nmethods_do(CodeBlobClosure* blk) const {
   292   if (_table != NULL) {
   299   if (_table != NULL) {
   293     _table->nmethods_do(blk);
   300     _table->nmethods_do(blk);