1 /*
2  * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
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
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 package sun.jvm.hotspot.oops;
26 
27 import java.io.*;
28 import java.util.*;
29 import sun.jvm.hotspot.debugger.*;
30 import sun.jvm.hotspot.runtime.*;
31 import sun.jvm.hotspot.types.*;
32 import sun.jvm.hotspot.utilities.*;
33 
34 //  ConstantPoolCache : A constant pool cache (ConstantPoolCache).
35 //  See cpCache.hpp for details about this class.
36 //
37 public class ConstantPoolCache extends Metadata {
38   static {
VM.registerVMInitializedObserver(new Observer() { public void update(Observable o, Object data) { initialize(VM.getVM().getTypeDataBase()); } })39     VM.registerVMInitializedObserver(new Observer() {
40         public void update(Observable o, Object data) {
41           initialize(VM.getVM().getTypeDataBase());
42         }
43       });
44   }
45 
initialize(TypeDataBase db)46   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
47     Type type      = db.lookupType("ConstantPoolCache");
48     constants      = new MetadataField(type.getAddressField("_constant_pool"), 0);
49     baseOffset     = type.getSize();
50     Type elType    = db.lookupType("ConstantPoolCacheEntry");
51     elementSize    = elType.getSize();
52     length         = new CIntField(type.getCIntegerField("_length"), 0);
53     intSize        = VM.getVM().getObjectHeap().getIntSize();
54     resolvedReferences = type.getAddressField("_resolved_references");
55     referenceMap   = type.getAddressField("_reference_map");
56   }
57 
ConstantPoolCache(Address addr)58   public ConstantPoolCache(Address addr) {
59     super(addr);
60   }
61 
isConstantPoolCache()62   public boolean isConstantPoolCache() { return true; }
63 
64   private static MetadataField constants;
65 
66   private static long baseOffset;
67   private static long elementSize;
68   private static CIntField length;
69   private static long intSize;
70   private static AddressField  resolvedReferences;
71   private static AddressField  referenceMap;
72 
getConstants()73   public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
74 
getSize()75   public long getSize() {
76     return alignSize(baseOffset + getLength() * elementSize);
77   }
78 
getEntryAt(int i)79   public ConstantPoolCacheEntry getEntryAt(int i) {
80     if (i < 0 || i >= getLength()) throw new IndexOutOfBoundsException(i + " " + getLength());
81     return new ConstantPoolCacheEntry(this, i);
82   }
83 
getIntAt(int entry, int fld)84   public int getIntAt(int entry, int fld) {
85     long offset = baseOffset + entry * elementSize + fld * intSize;
86     return (int) getAddress().getCIntegerAt(offset, intSize, true );
87   }
88 
89 
printValueOn(PrintStream tty)90   public void printValueOn(PrintStream tty) {
91     tty.print("ConstantPoolCache for " + getConstants().getPoolHolder().getName().asString() + " address = " + getAddress() + " offset = " + baseOffset);
92   }
93 
getLength()94   public int getLength() {
95     return (int) length.getValue(getAddress());
96   }
97 
iterateFields(MetadataVisitor visitor)98   public void iterateFields(MetadataVisitor visitor) {
99     super.iterateFields(visitor);
100     visitor.doMetadata(constants, true);
101       for (int i = 0; i < getLength(); i++) {
102         ConstantPoolCacheEntry entry = getEntryAt(i);
103         entry.iterateFields(visitor);
104       }
105     }
106 
getResolvedReferences()107   public Oop getResolvedReferences() {
108     Address handle = resolvedReferences.getValue(getAddress());
109     if (handle != null) {
110       // Load through the handle
111       OopHandle refs = handle.getOopHandleAt(0);
112       return VM.getVM().getObjectHeap().newOop(refs);
113     }
114     return null;
115   }
116 
referenceMap()117   public U2Array referenceMap() {
118     return new U2Array(referenceMap.getValue(getAddress()));
119   }
120 };
121