8071962: The SA code needs to be updated to support Symbol lookup from the shared archive
Support shared symbols lookup. Reviewed-by: minqi, sspitsyn, dsamersoff, iklam
This commit is contained in:
parent
62166e9f59
commit
dc9bb3c201
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -44,15 +44,22 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
|
||||
private static synchronized void initialize(TypeDataBase db) {
|
||||
Type type = db.lookupType("SymbolTable");
|
||||
theTableField = type.getAddressField("_the_table");
|
||||
sharedTableField = type.getAddressField("_shared_table");
|
||||
}
|
||||
|
||||
// Fields
|
||||
private static AddressField theTableField;
|
||||
private static AddressField sharedTableField;
|
||||
|
||||
private CompactHashTable sharedTable;
|
||||
|
||||
// Accessors
|
||||
public static SymbolTable getTheTable() {
|
||||
Address tmp = theTableField.getValue();
|
||||
return (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
|
||||
SymbolTable table = (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
|
||||
Address shared = sharedTableField.getStaticFieldAddress();
|
||||
table.sharedTable = (CompactHashTable)VMObjectFactory.newObject(CompactHashTable.class, shared);
|
||||
return table;
|
||||
}
|
||||
|
||||
public SymbolTable(Address addr) {
|
||||
@ -73,8 +80,9 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
|
||||
|
||||
/** Clone of VM's "temporary" probe routine, as the SA currently
|
||||
does not support mutation so lookup() would have no effect
|
||||
anyway. Returns null if the given string is not in the symbol
|
||||
table. */
|
||||
anyway. Searches the regular symbol table and the shared symbol
|
||||
table. Null is returned if the given name is not found in both
|
||||
tables. */
|
||||
public Symbol probe(byte[] name) {
|
||||
long hashValue = hashSymbol(name);
|
||||
for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
|
||||
@ -85,7 +93,8 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
return sharedTable.probe(name, hashValue);
|
||||
}
|
||||
|
||||
public interface SymbolVisitor {
|
||||
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.jvm.hotspot.utilities;
|
||||
|
||||
import java.util.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.oops.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.utilities.*;
|
||||
|
||||
public class CompactHashTable extends VMObject {
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||
Type type = db.lookupType("SymbolCompactHashTable");
|
||||
baseAddressField = type.getAddressField("_base_address");
|
||||
bucketCountField = type.getCIntegerField("_bucket_count");
|
||||
tableEndOffsetField = type.getCIntegerField("_table_end_offset");
|
||||
bucketsField = type.getAddressField("_buckets");
|
||||
uintSize = db.lookupType("juint").getSize();
|
||||
}
|
||||
|
||||
// Fields
|
||||
private static CIntegerField bucketCountField;
|
||||
private static CIntegerField tableEndOffsetField;
|
||||
private static AddressField baseAddressField;
|
||||
private static AddressField bucketsField;
|
||||
private static long uintSize;
|
||||
|
||||
private static int BUCKET_OFFSET_MASK = 0x3FFFFFFF;
|
||||
private static int BUCKET_TYPE_SHIFT = 30;
|
||||
private static int COMPACT_BUCKET_TYPE = 1;
|
||||
|
||||
public CompactHashTable(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
private int bucketCount() {
|
||||
return (int)bucketCountField.getValue(addr);
|
||||
}
|
||||
|
||||
private int tableEndOffset() {
|
||||
return (int)tableEndOffsetField.getValue(addr);
|
||||
}
|
||||
|
||||
private boolean isCompactBucket(int bucket_info) {
|
||||
return (bucket_info >> BUCKET_TYPE_SHIFT) == COMPACT_BUCKET_TYPE;
|
||||
}
|
||||
|
||||
private int bucketOffset(int bucket_info) {
|
||||
return bucket_info & BUCKET_OFFSET_MASK;
|
||||
}
|
||||
|
||||
public Symbol probe(byte[] name, long hash) {
|
||||
long symOffset;
|
||||
Symbol sym;
|
||||
Address baseAddress = baseAddressField.getValue(addr);
|
||||
Address bucket = bucketsField.getValue(addr);
|
||||
Address bucketEnd = bucket;
|
||||
long index = hash % bucketCount();
|
||||
int bucketInfo = (int)bucket.getCIntegerAt(index * uintSize, uintSize, true);
|
||||
int bucketOffset = bucketOffset(bucketInfo);
|
||||
int nextBucketInfo = (int)bucket.getCIntegerAt((index+1) * uintSize, uintSize, true);
|
||||
int nextBucketOffset = bucketOffset(nextBucketInfo);
|
||||
|
||||
bucket = bucket.addOffsetTo(bucketOffset * uintSize);
|
||||
|
||||
if (isCompactBucket(bucketInfo)) {
|
||||
symOffset = bucket.getCIntegerAt(0, uintSize, true);
|
||||
sym = Symbol.create(baseAddress.addOffsetTo(symOffset));
|
||||
if (sym.equals(name)) {
|
||||
return sym;
|
||||
}
|
||||
} else {
|
||||
bucketEnd = bucket.addOffsetTo(nextBucketOffset * uintSize);
|
||||
while (bucket.lessThan(bucketEnd)) {
|
||||
long symHash = bucket.getCIntegerAt(0, uintSize, true);
|
||||
if (symHash == hash) {
|
||||
symOffset = bucket.getCIntegerAt(uintSize, uintSize, true);
|
||||
Address symAddr = baseAddress.addOffsetTo(symOffset);
|
||||
sym = Symbol.create(symAddr);
|
||||
if (sym.equals(name)) {
|
||||
return sym;
|
||||
}
|
||||
}
|
||||
bucket = bucket.addOffsetTo(2 * uintSize);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -188,6 +188,7 @@ public:
|
||||
// dump time.
|
||||
//
|
||||
template <class T, class N> class CompactHashtable VALUE_OBJ_CLASS_SPEC {
|
||||
friend class VMStructs;
|
||||
uintx _base_address;
|
||||
juint _entry_count;
|
||||
juint _bucket_count;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,6 +27,7 @@
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/loaderConstraints.hpp"
|
||||
#include "classfile/placeholders.hpp"
|
||||
#include "classfile/compactHashtable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "ci/ciField.hpp"
|
||||
@ -243,6 +244,7 @@ typedef TwoOopHashtable<Klass*, mtClass> KlassTwoOopHashtable;
|
||||
typedef Hashtable<Klass*, mtClass> KlassHashtable;
|
||||
typedef HashtableEntry<Klass*, mtClass> KlassHashtableEntry;
|
||||
typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
|
||||
typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// VM_STRUCTS
|
||||
@ -624,6 +626,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
|
||||
/***************/ \
|
||||
\
|
||||
static_field(SymbolTable, _the_table, SymbolTable*) \
|
||||
static_field(SymbolTable, _shared_table, SymbolCompactHashTable) \
|
||||
\
|
||||
/***************/ \
|
||||
/* StringTable */ \
|
||||
@ -632,6 +635,16 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
|
||||
static_field(StringTable, _the_table, StringTable*) \
|
||||
\
|
||||
/********************/ \
|
||||
/* CompactHashTable */ \
|
||||
/********************/ \
|
||||
\
|
||||
nonstatic_field(SymbolCompactHashTable, _base_address, uintx) \
|
||||
nonstatic_field(SymbolCompactHashTable, _entry_count, juint) \
|
||||
nonstatic_field(SymbolCompactHashTable, _bucket_count, juint) \
|
||||
nonstatic_field(SymbolCompactHashTable, _table_end_offset, juint) \
|
||||
nonstatic_field(SymbolCompactHashTable, _buckets, juint*) \
|
||||
\
|
||||
/********************/ \
|
||||
/* SystemDictionary */ \
|
||||
/********************/ \
|
||||
\
|
||||
@ -1580,6 +1593,8 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
|
||||
declare_type(ResourceArea, Arena) \
|
||||
declare_toplevel_type(Chunk) \
|
||||
\
|
||||
declare_toplevel_type(SymbolCompactHashTable) \
|
||||
\
|
||||
/***********************************************************/ \
|
||||
/* Thread hierarchy (needed for run-time type information) */ \
|
||||
/***********************************************************/ \
|
||||
|
Loading…
Reference in New Issue
Block a user