/* * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.google.gwt.dev.jjs.impl.gflow.liveness; import com.google.gwt.dev.jjs.ast.JVariable; import com.google.gwt.dev.jjs.impl.gflow.Assumption; import com.google.gwt.dev.util.collect.IdentityHashSet; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; /** * Assumption for LivenessAnalysis. Contains set of all live (=used after) * variables. */ public class LivenessAssumption implements Assumption<LivenessAssumption> { /** * Updates the assumption by copying it on first write. */ public static class Updater { private LivenessAssumption assumption; private boolean copied = false; public Updater(LivenessAssumption assumption) { this.assumption = assumption; } public void kill(JVariable target) { if (assumption == null || !assumption.isLive(target)) { return; } copyIfNeeded(); assumption.kill(target); } public LivenessAssumption unwrap() { if (assumption != null && assumption.liveVariables.isEmpty()) { return null; } return assumption; } public void use(JVariable target) { copyIfNeeded(); assumption.use(target); } private void copyIfNeeded() { if (!copied) { assumption = new LivenessAssumption(assumption); copied = true; } } } /** * Set of all live variables. */ private final Set<JVariable> liveVariables = new IdentityHashSet<JVariable>(); public LivenessAssumption() { super(); } public LivenessAssumption(LivenessAssumption assumptions) { if (assumptions != null) { this.liveVariables.addAll(assumptions.liveVariables); } } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } LivenessAssumption other = (LivenessAssumption) obj; return liveVariables.equals(other.liveVariables); } @Override public int hashCode() { return liveVariables.hashCode(); } public boolean isLive(JVariable variable) { return liveVariables.contains(variable); } /** * Computes union of all live variables. */ public LivenessAssumption join(LivenessAssumption value) { if (value == null || value.liveVariables.isEmpty()) { return this; } if (liveVariables.isEmpty()) { return value; } LivenessAssumption result = new LivenessAssumption(this); result.liveVariables.addAll(value.liveVariables); return result; } public String toDebugString() { StringBuffer result = new StringBuffer(); result.append("{"); List<JVariable> vars = new ArrayList<JVariable>(liveVariables); Collections.sort(vars, new Comparator<JVariable>() { public int compare(JVariable o1, JVariable o2) { return o1.getName().compareTo(o2.getName()); } }); for (JVariable variable : vars) { if (result.length() > 1) { result.append(", "); } result.append(variable.getName()); } result.append("}"); return result.toString(); } @Override public String toString() { return toDebugString(); } private void kill(JVariable variable) { liveVariables.remove(variable); } private void use(JVariable variable) { liveVariables.add(variable); } }