001/*
002 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.compiler.common.type;
024
025import jdk.internal.jvmci.meta.*;
026
027/**
028 * Abstract base class of all pointer types.
029 */
030public abstract class AbstractPointerStamp extends Stamp {
031
032    private final boolean nonNull;
033    private final boolean alwaysNull;
034
035    protected AbstractPointerStamp(boolean nonNull, boolean alwaysNull) {
036        this.nonNull = nonNull;
037        this.alwaysNull = alwaysNull;
038    }
039
040    public boolean nonNull() {
041        assert !this.isEmpty() || nonNull;
042        return nonNull;
043    }
044
045    public boolean alwaysNull() {
046        return alwaysNull;
047    }
048
049    protected abstract AbstractPointerStamp copyWith(boolean newNonNull, boolean newAlwaysNull);
050
051    @Override
052    public int hashCode() {
053        final int prime = 31;
054        int result = 1;
055        result = prime * result + (alwaysNull ? 1231 : 1237);
056        result = prime * result + (nonNull ? 1231 : 1237);
057        return result;
058    }
059
060    @Override
061    public Stamp join(Stamp stamp) {
062        AbstractPointerStamp other = (AbstractPointerStamp) stamp;
063        boolean joinNonNull = this.nonNull || other.nonNull;
064        boolean joinAlwaysNull = this.alwaysNull || other.alwaysNull;
065        if (joinNonNull && joinAlwaysNull) {
066            return empty();
067        } else {
068            return copyWith(joinNonNull, joinAlwaysNull);
069        }
070    }
071
072    @Override
073    public Stamp improveWith(Stamp other) {
074        return join(other);
075    }
076
077    @Override
078    public Stamp meet(Stamp stamp) {
079        AbstractPointerStamp other = (AbstractPointerStamp) stamp;
080        boolean meetNonNull = this.nonNull && other.nonNull;
081        boolean meetAlwaysNull = this.alwaysNull && other.alwaysNull;
082        return copyWith(meetNonNull, meetAlwaysNull);
083    }
084
085    @Override
086    public Stamp unrestricted() {
087        return copyWith(false, false);
088    }
089
090    @Override
091    public boolean equals(Object obj) {
092        if (this == obj) {
093            return true;
094        }
095        if (obj == null || getClass() != obj.getClass()) {
096            return false;
097        }
098        AbstractPointerStamp other = (AbstractPointerStamp) obj;
099        return this.alwaysNull == other.alwaysNull && this.nonNull == other.nonNull;
100    }
101
102    @Override
103    public Constant asConstant() {
104        if (alwaysNull) {
105            return JavaConstant.NULL_POINTER;
106        } else {
107            return null;
108        }
109    }
110
111    @Override
112    public Kind getStackKind() {
113        return Kind.Illegal;
114    }
115}