/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.mmtk.harness.lang.pcode; import org.mmtk.harness.Harness; import org.mmtk.harness.exception.OutOfMemory; import org.mmtk.harness.lang.Env; import org.mmtk.harness.lang.ast.AST; import org.mmtk.harness.lang.compiler.Register; import org.mmtk.harness.lang.runtime.ObjectValue; import org.mmtk.harness.lang.runtime.StackFrame; import org.mmtk.harness.lang.type.Type; import org.mmtk.harness.lang.type.UserType; import org.mmtk.harness.vm.ObjectModel; import org.vmmagic.unboxed.ObjectReference; /** * Object allocation operation. 3 operands: * - # data words * - # reference words * - alignment * Always produces a result. */ public final class AllocUserOp extends UnaryOp { /** Call site */ private final int site; private final int dataCount; private final int refCount; private final Type type; /** * Allocate an object of the given user-defined type * @param source Source code AST element best corresponding to this op * @param resultTemp Register to store the result in * @param type Type of object to allocate * @param doubleAlign Does the object require double-word alignment ? * @param site Call site identifier */ public AllocUserOp(AST source, Register resultTemp, UserType type, Register doubleAlign, int site) { super(source,"alloc",resultTemp,doubleAlign); this.site = site; this.dataCount = type.dataFieldCount(); this.refCount = type.referenceFieldCount(); this.type = type; } /** Get the alignment operand from <code>frame</code> */ private boolean getDoubleAlign(StackFrame frame) { return frame.get(operand).getBoolValue(); } /** * @see PseudoOp#exec(Env) */ @Override public void exec(Env env) { StackFrame frame = env.top(); ObjectReference object; try { object = env.alloc(refCount, dataCount, getDoubleAlign(frame), site); } catch (OutOfMemory e) { throw e; } catch (Exception e) { throw new RuntimeException("Error allocating object id:"+ObjectModel.lastObjectId()+" refs:"+refCount+ " ints: "+dataCount+" align:"+getDoubleAlign(frame)+" site:"+site,e); } setResult(frame,new ObjectValue(object)); if (Harness.gcEveryAlloc()) { env.gc(); } } /** * String representation of this operation * tx <- alloc(type) */ @Override public String toString() { return super.toString() + "(" + type.getName() + ")"; } }