001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.jikesrvm.compilers.opt.ir.operand;
014    
015    import org.jikesrvm.VM;
016    import org.jikesrvm.classloader.Atom;
017    import org.jikesrvm.classloader.BootstrapClassLoader;
018    import org.jikesrvm.classloader.TypeReference;
019    import org.vmmagic.unboxed.Offset;
020    import org.jikesrvm.mm.mminterface.MemoryManager;
021    
022    /**
023     * Represents a constant object operand (for example, from an
024     * initialized static final).
025     *
026     * @see Operand
027     */
028    public class ObjectConstantOperand extends ConstantOperand {
029    
030      /**
031       * The non-null object value
032       */
033      public final Object value;
034    
035      /**
036       * Offset in JTOC where this object constant lives.
037       */
038      public final Offset offset;
039    
040      /**
041       * Can this object be moved in memory?
042       */
043      private final boolean movable;
044    
045      /**
046       * Construct a new object constant operand
047       *
048       * @param v the object constant
049       * @param i JTOC offset of the object constant
050       */
051      public ObjectConstantOperand(Object v, Offset i) {
052        if (VM.VerifyAssertions) VM._assert(v != null);
053        value = v;
054        offset = i;
055        // prior to writing the boot image we don't know where objects will reside,
056        // so we must treat them as movable when writing the boot image
057        movable = !VM.runningVM || !MemoryManager.willNeverMove(v);
058      }
059    
060      /**
061       * Return a new operand that is semantically equivalent to <code>this</code>.
062       *
063       * @return a copy of <code>this</code>
064       */
065      public Operand copy() {
066        return new ObjectConstantOperand(value, offset);
067      }
068    
069      /**
070       * Return the {@link TypeReference} of the value represented by the operand.
071       *
072       * @return type reference for type of object
073       */
074      public TypeReference getType() {
075        if (VM.runningVM) {
076          return java.lang.JikesRVMSupport.getTypeForClass(value.getClass()).getTypeRef();
077        } else {
078          Class<?> rc = value.getClass();
079          String className = rc.getName();
080          Atom classAtom = Atom.findOrCreateAsciiAtom(className.replace('.', '/'));
081          if (className.startsWith("[")) {
082            // an array
083            return TypeReference.findOrCreate(BootstrapClassLoader.getBootstrapClassLoader(), classAtom);
084          } else {
085            // a class
086            Atom classDescriptor = classAtom.descriptorFromClassName();
087            return TypeReference.findOrCreate(BootstrapClassLoader.getBootstrapClassLoader(), classDescriptor);
088          }
089        }
090      }
091    
092      /**
093       * Does the operand represent a value of the reference data type?
094       *
095       * @return <code>true</code>
096       */
097      public final boolean isRef() {
098        return true;
099      }
100    
101      /**
102       * Is the operand a movable {@link ObjectConstantOperand}?
103       *
104       * @return movable
105       */
106      public boolean isMovableObjectConstant() {
107        return movable;
108      }
109    
110    
111      /**
112       * Are two operands semantically equivalent?
113       *
114       * @param op other operand
115       * @return   <code>true</code> if <code>this</code> and <code>op</code>
116       *           are semantically equivalent or <code>false</code>
117       *           if they are not.
118       */
119      public boolean similar(Operand op) {
120        return (op instanceof ObjectConstantOperand) && value.equals(((ObjectConstantOperand) op).value);
121      }
122    
123      /**
124       * Returns the string representation of this operand.
125       *
126       * @return a string representation of this operand.
127       */
128      public String toString() {
129        return "object \"" + value + "\"";
130      }
131    }