0N/A/*
2273N/A * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
1879N/A#include "precompiled.hpp"
1879N/A#include "classfile/resolutionErrors.hpp"
1879N/A#include "memory/resourceArea.hpp"
1879N/A#include "oops/oop.inline.hpp"
1879N/A#include "runtime/handles.inline.hpp"
1879N/A#include "runtime/safepoint.hpp"
1879N/A#include "utilities/hashtable.inline.hpp"
0N/A
0N/A// add new entry to the table
0N/Avoid ResolutionErrorTable::add_entry(int index, unsigned int hash,
2062N/A constantPoolHandle pool, int cp_index, Symbol* error)
0N/A{
0N/A assert_locked_or_safepoint(SystemDictionary_lock);
2062N/A assert(!pool.is_null() && error != NULL, "adding NULL obj");
0N/A
2062N/A ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error);
0N/A add_entry(index, entry);
0N/A}
0N/A
0N/A// find entry in the table
0N/AResolutionErrorEntry* ResolutionErrorTable::find_entry(int index, unsigned int hash,
0N/A constantPoolHandle pool, int cp_index)
0N/A{
0N/A assert_locked_or_safepoint(SystemDictionary_lock);
0N/A
0N/A for (ResolutionErrorEntry *error_probe = bucket(index);
0N/A error_probe != NULL;
0N/A error_probe = error_probe->next()) {
0N/A if (error_probe->hash() == hash && error_probe->pool() == pool()) {
0N/A return error_probe;;
0N/A }
0N/A }
0N/A return NULL;
0N/A}
0N/A
2062N/Avoid ResolutionErrorEntry::set_error(Symbol* e) {
2062N/A assert(e == NULL || _error == NULL, "cannot reset error");
2062N/A _error = e;
2062N/A if (_error != NULL) _error->increment_refcount();
2062N/A}
2062N/A
0N/A// create new error entry
0N/AResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, constantPoolOop pool,
2062N/A int cp_index, Symbol* error)
0N/A{
3863N/A ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<constantPoolOop, mtClass>::new_entry(hash, pool);
0N/A entry->set_cp_index(cp_index);
2062N/A NOT_PRODUCT(entry->set_error(NULL);)
0N/A entry->set_error(error);
0N/A
0N/A return entry;
0N/A}
0N/A
2062N/Avoid ResolutionErrorTable::free_entry(ResolutionErrorEntry *entry) {
2062N/A // decrement error refcount
2062N/A assert(entry->error() != NULL, "error should be set");
2062N/A entry->error()->decrement_refcount();
3863N/A Hashtable<constantPoolOop, mtClass>::free_entry(entry);
2062N/A}
2062N/A
2062N/A
0N/A// create resolution error table
0N/AResolutionErrorTable::ResolutionErrorTable(int table_size)
3863N/A : Hashtable<constantPoolOop, mtClass>(table_size, sizeof(ResolutionErrorEntry)) {
0N/A}
0N/A
0N/A// GC support
0N/Avoid ResolutionErrorTable::oops_do(OopClosure* f) {
0N/A for (int i = 0; i < table_size(); i++) {
0N/A for (ResolutionErrorEntry* probe = bucket(i);
0N/A probe != NULL;
0N/A probe = probe->next()) {
0N/A assert(probe->pool() != (constantPoolOop)NULL, "resolution error table is corrupt");
2062N/A assert(probe->error() != (Symbol*)NULL, "resolution error table is corrupt");
0N/A probe->oops_do(f);
0N/A }
0N/A }
0N/A}
0N/A
0N/A// GC support
0N/Avoid ResolutionErrorEntry::oops_do(OopClosure* blk) {
0N/A blk->do_oop((oop*)pool_addr());
0N/A}
0N/A
0N/A// Remove unloaded entries from the table
0N/Avoid ResolutionErrorTable::purge_resolution_errors(BoolObjectClosure* is_alive) {
1409N/A assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
0N/A for (int i = 0; i < table_size(); i++) {
0N/A for (ResolutionErrorEntry** p = bucket_addr(i); *p != NULL; ) {
0N/A ResolutionErrorEntry* entry = *p;
0N/A assert(entry->pool() != (constantPoolOop)NULL, "resolution error table is corrupt");
0N/A constantPoolOop pool = entry->pool();
0N/A if (is_alive->do_object_b(pool)) {
0N/A p = entry->next_addr();
0N/A } else {
0N/A *p = entry->next();
0N/A free_entry(entry);
0N/A }
0N/A }
0N/A }
0N/A}