test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectTestBase.java
author kvn
Tue, 29 Oct 2019 15:35:06 -0700
changeset 58851 f1e6442241ca
child 59103 4a09d4df104c
permissions -rw-r--r--
8233035: Update JVMCI Reviewed-by: dlong

/*
 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package jdk.vm.ci.code.test;

import java.util.Arrays;

import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaValue;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.runtime.JVMCI;

public abstract class VirtualObjectTestBase {

    public static class SimpleObject {
        int i1;
        int i2;
        int i3;
        int i4;
        int i5;
        int i6;
    }

    public static JavaConstant getValue(JavaKind kind) {
        long dummyValue = kind.ordinal();
        dummyValue = dummyValue | dummyValue << 8;
        dummyValue = dummyValue | dummyValue << 16;
        dummyValue = dummyValue | dummyValue << 32;
        if (kind.isNumericInteger()) {
            return JavaConstant.forIntegerKind(kind, dummyValue);
        } else if (kind == JavaKind.Float) {
            return JavaConstant.forDouble(Double.longBitsToDouble(dummyValue));
        } else if (kind == JavaKind.Float) {
            return JavaConstant.forFloat(Float.intBitsToFloat((int) dummyValue));
        } else {
            return JavaConstant.NULL_POINTER;
        }
    }

    public static JavaValue[] getJavaValues(JavaKind[] kinds) {
        JavaValue[] values = new JavaValue[kinds.length];
        for (int i = 0; i < kinds.length; i++) {
            values[i] = getValue(kinds[i]);
        }
        return values;
    }

    /**
     * Subclasses are expected to override this method to provide their own verification logic using
     * the normal JUnit {@link org.junit.Assert} methods.
     *
     * @param klass class for the {@link jdk.vm.ci.code.VirtualObject}
     * @param kinds {@link JavaKind Javakinds} for values
     * @param values {@link JavaValue values} for materializing the
     *            {@link jdk.vm.ci.code.VirtualObject}
     * @param malformed indicates whether the resulting virtual object is considered to be properly
     *            formed relative to the fields of {@code klass}
     * @throws AssertionError if a problem is detected
     */
    protected abstract void test(ResolvedJavaType klass, JavaValue[] kinds, JavaKind[] values, boolean malformed);

    public void testBase() {
        MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();

        ResolvedJavaType simple = metaAccess.lookupJavaType(SimpleObject.class);
        ResolvedJavaField[] fields = simple.getInstanceFields(true);

        JavaKind[] fieldKinds = new JavaKind[fields.length];
        for (int i = 0; i < fields.length; i++) {
            fieldKinds[i] = fields[i].getType().getJavaKind();
        }

        // Generate a straightforward VirtualObject with values that match to declared field types.
        JavaKind[] kinds = fieldKinds.clone();
        JavaValue[] values = getJavaValues(kinds);
        test(simple, values, kinds, false);

        // Spread a long value across two int fields
        kinds = Arrays.copyOf(fieldKinds, fieldKinds.length - 1);
        kinds[1] = JavaKind.Long;
        test(simple, getJavaValues(kinds), kinds, false);

        // Produce a long value for the final int field so there is no matching int field for the
        // second half of the long
        kinds = fieldKinds.clone();
        kinds[kinds.length - 1] = JavaKind.Long;
        test(simple, getJavaValues(kinds), kinds, true);

        // Not enough values for the fields.
        kinds = Arrays.copyOf(fieldKinds, fieldKinds.length - 1);
        test(simple, getJavaValues(kinds), kinds, true);

        // Too many values for the fields.
        kinds = Arrays.copyOf(fieldKinds, fieldKinds.length + 1);
        kinds[kinds.length - 1] = JavaKind.Int;
        test(simple, getJavaValues(kinds), kinds, true);
    }
}