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 }