VirtualConstructor.java revision 9883:903a2e023ffb
1279377Simp/*
2279377Simp * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
3279377Simp * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4279377Simp *
5279377Simp * This code is free software; you can redistribute it and/or modify it
6279377Simp * under the terms of the GNU General Public License version 2 only, as
7279377Simp * published by the Free Software Foundation.
8279377Simp *
9279377Simp * This code is distributed in the hope that it will be useful, but WITHOUT
10279377Simp * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11279377Simp * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12279377Simp * version 2 for more details (a copy is included in the LICENSE file that
13279377Simp * accompanied this code).
14279377Simp *
15279377Simp * You should have received a copy of the GNU General Public License version
16279377Simp * 2 along with this work; if not, write to the Free Software Foundation,
17279377Simp * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18279377Simp *
19279377Simp * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20279377Simp * or visit www.oracle.com if you need additional information or have any
21279377Simp * questions.
22279377Simp *
23279377Simp */
24279377Simp
25279377Simppackage sun.jvm.hotspot.runtime;
26279377Simp
27279377Simpimport java.util.*;
28279377Simpimport sun.jvm.hotspot.debugger.*;
29279377Simpimport sun.jvm.hotspot.types.*;
30279377Simp
31279377Simp/** This class provides generalized "virtual constructor"
32279377Simp    functionality for VMObjects. In simple terms, it creates
33279377Simp    correctly-typed Java wrapper objects for underlying Addresses,
34279377Simp    using the "RTTI-like" functionality of TypeDataBase. For example,
35279377Simp    if the given Address really is a DefNewGeneration*, the Java object
36279377Simp    created for it will be of type
37279377Simp    sun.jvm.hotspot.memory.DefNewGeneration, assuming the mapping from
38279377Simp    type "DefNewGeneration" to class
39279377Simp    sun.jvm.hotspot.memory.DefNewGeneration has been set up. */
40279377Simp
41279377Simppublic class VirtualConstructor extends InstanceConstructor<VMObject> {
42279377Simp  private TypeDataBase db;
43279377Simp  private Map          map; // Map<String, Class>
44279377Simp
45279377Simp  public VirtualConstructor(TypeDataBase db) {
46279377Simp    this.db = db;
47279377Simp    map     = new HashMap();
48279377Simp  }
49279377Simp
50279377Simp  /** Adds a mapping from the given C++ type name to the given Java
51279377Simp      class. The latter must be a subclass of
52279377Simp      sun.jvm.hotspot.runtime.VMObject. Returns false if there was
53279377Simp      already a class for this type name in the map. */
54279377Simp  public boolean addMapping(String cTypeName, Class clazz) {
55279377Simp    if (map.get(cTypeName) != null) {
56279377Simp      return false;
57279377Simp    }
58279377Simp
59279377Simp    map.put(cTypeName, clazz);
60279377Simp    return true;
61279377Simp  }
62279377Simp
63279377Simp  /** Instantiate the most-precisely typed wrapper object available
64279377Simp      for the type of the given Address. If no type in the mapping
65279377Simp      matched the type of the Address, throws a WrongTypeException.
66279377Simp      Returns null for a null address (similar behavior to
67279377Simp      VMObjectFactory). */
68279377Simp  public VMObject instantiateWrapperFor(Address addr) throws WrongTypeException {
69279377Simp    if (addr == null) {
70279377Simp      return null;
71279377Simp    }
72279377Simp
73279377Simp    for (Iterator iter = map.keySet().iterator(); iter.hasNext(); ) {
74279377Simp      String typeName = (String) iter.next();
75279377Simp      if (db.addressTypeIsEqualToType(addr, db.lookupType(typeName))) {
76279377Simp        return (VMObject) VMObjectFactory.newObject((Class) map.get(typeName), addr);
77279377Simp      }
78279377Simp    }
79279377Simp
80279377Simp    throw newWrongTypeException(addr);
81279377Simp  }
82279377Simp}
83279377Simp