/* * 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.jikesrvm.compilers.opt.bc2ir; import org.jikesrvm.VM; import org.jikesrvm.compilers.opt.ir.operand.Operand; /** * Simulates the Java stack for abstract interpretation in {@link BC2IR}.<p> * * This class is intended to be used by a single thread. Methods from this * class do not provide any error handling.<p> * * The total amount of {@link Operand}s that can be accepted by an operand stack * is called the capacity of the operand stack. It is determined when the stack is * created. The capacity is distinct from the current number of operands on the stack * which is called the size of the operand stack. */ final class OperandStack { private final Operand[] stack; private int top; /** * Creates an operand stack. * * @param capacity the maximum number of operands that the stack * must be able to hold, must be {@code >= 0} */ OperandStack(int capacity) { stack = new Operand[capacity]; top = 0; } void push(Operand val) { // if (VM.VerifyAssertions) VM._assert(val.instruction == null); stack[top++] = val; } Operand pop() { return stack[--top]; } /** * Pops the two topmost operands from the stack and discards them.<p> * * This implements the pop2 bytecode. */ void pop2() { pop(); pop(); } Operand getFromBottom(int pos) { return stack[pos]; } Operand getFromTop(int n) { return stack[top - n - 1]; } void replaceFromTop(int n, Operand op) { if (VM.VerifyAssertions) VM._assert(op.instruction == null); stack[top - n - 1] = op; } /** * Swaps the two topmost operands on the stack.<p> * * This implements the swap bytecode. */ void swap() { Operand v1 = pop(); Operand v2 = pop(); push(v1); push(v2); } void clear() { top = 0; } /** * Returns a deep copy of the stack.<p> * * The copied stack has copies of the operands from the original stack. The * size and capacity of the copied stack are equal to the original stack * at the time of the copy. * * @return a copy of the stack */ OperandStack deepCopy() { OperandStack newss = new OperandStack(stack.length); newss.top = top; for (int i = 0; i < top; i++) { // deep copy of stack newss.stack[i] = stack[i].copy(); } return newss; } boolean isEmpty() { return (top == 0); } /** * Returns the current size of the stack. * * @return the current number of operands on the stack */ int getSize() { return top; } /** * Returns a new, empty operand stack that has the same capacity * as this one. * @return a new operand stack */ OperandStack createEmptyOperandStackWithSameCapacity() { return new OperandStack(stack.length); } }