View Javadoc
1   /*
2    * Copyright (c) 2000, 2012, 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  // ObjArrayKlass is the klass for ObjArrays
35  
36  public class ObjArrayKlass extends ArrayKlass {
37    static {
38      VM.registerVMInitializedObserver(new Observer() {
39          public void update(Observable o, Object data) {
40            initialize(VM.getVM().getTypeDataBase());
41          }
42        });
43    }
44  
45    private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
46      Type type = db.lookupType("ObjArrayKlass");
47      elementKlass = new MetadataField(type.getAddressField("_element_klass"), 0);
48      bottomKlass  = new MetadataField(type.getAddressField("_bottom_klass"), 0);
49    }
50  
51    public ObjArrayKlass(Address addr) {
52      super(addr);
53    }
54  
55    private static MetadataField elementKlass;
56    private static MetadataField bottomKlass;
57  
58    public Klass getElementKlass() { return (Klass) elementKlass.getValue(this); }
59    public Klass getBottomKlass()  { return (Klass) bottomKlass.getValue(this); }
60  
61    public long computeModifierFlags() {
62      long elementFlags = getElementKlass().computeModifierFlags();
63      long arrayFlags = 0L;
64      if ((elementFlags & (JVM_ACC_PUBLIC | JVM_ACC_PROTECTED)) != 0) {
65         // The array type is public if the component type is public or protected
66         arrayFlags = JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC;
67      } else {
68         // The array type is private if the component type is private
69         arrayFlags = JVM_ACC_ABSTRACT | JVM_ACC_FINAL;
70      }
71      return arrayFlags;
72    }
73  
74    public void iterateFields(MetadataVisitor visitor) {
75      super.iterateFields(visitor);
76      visitor.doMetadata(elementKlass, true);
77      visitor.doMetadata(bottomKlass, true);
78    }
79  
80    public Klass arrayKlassImpl(boolean orNull, int n) {
81      if (Assert.ASSERTS_ENABLED) {
82        Assert.that(getDimension() <= n, "check order of chain");
83      }
84      int dimension = (int) getDimension();
85      if (dimension == n) {
86        return this;
87      }
88      ObjArrayKlass ak = (ObjArrayKlass) getHigherDimension();
89      if (ak == null) {
90        if (orNull) return null;
91        // FIXME: would need to change in reflective system to actually
92        // allocate klass
93        throw new RuntimeException("Can not allocate array klasses in debugging system");
94      }
95  
96      if (orNull) {
97        return ak.arrayKlassOrNull(n);
98      }
99      return ak.arrayKlass(n);
100   }
101 
102   public Klass arrayKlassImpl(boolean orNull) {
103     return arrayKlassImpl(orNull, (int) (getDimension() + 1));
104   }
105 
106   public void printValueOn(PrintStream tty) {
107     tty.print("ObjArrayKlass for ");
108     getElementKlass().printValueOn(tty);
109   }
110 };