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-{@code 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      @Override
061      public Operand copy() {
062        return new ObjectConstantOperand(value, offset);
063      }
064    
065      @Override
066      public TypeReference getType() {
067        if (VM.runningVM) {
068          return java.lang.JikesRVMSupport.getTypeForClass(value.getClass()).getTypeRef();
069        } else {
070          Class<?> rc = value.getClass();
071          String className = rc.getName();
072          Atom classAtom = Atom.findOrCreateAsciiAtom(className.replace('.', '/'));
073          if (className.startsWith("[")) {
074            // an array
075            return TypeReference.findOrCreate(BootstrapClassLoader.getBootstrapClassLoader(), classAtom);
076          } else {
077            // a class
078            Atom classDescriptor = classAtom.descriptorFromClassName();
079            return TypeReference.findOrCreate(BootstrapClassLoader.getBootstrapClassLoader(), classDescriptor);
080          }
081        }
082      }
083    
084      @Override
085      public final boolean isRef() {
086        return true;
087      }
088    
089      /**
090       * @return {@link #movable}
091       */
092      @Override
093      public boolean isMovableObjectConstant() {
094        return movable;
095      }
096    
097    
098      @Override
099      public boolean similar(Operand op) {
100        return (op instanceof ObjectConstantOperand) && value.equals(((ObjectConstantOperand) op).value);
101      }
102    
103      /**
104       * Returns the string representation of this operand.
105       *
106       * @return a string representation of this operand.
107       */
108      @Override
109      public String toString() {
110        return "object \"" + value + "\"";
111      }
112    }