diff --git a/src/hotspot/share/c1/c1_Canonicalizer.cpp b/src/hotspot/share/c1/c1_Canonicalizer.cpp index e8b8f45cc70..d6859c44031 100644 --- a/src/hotspot/share/c1/c1_Canonicalizer.cpp +++ b/src/hotspot/share/c1/c1_Canonicalizer.cpp @@ -646,8 +646,7 @@ void Canonicalizer::do_NewObjectArray (NewObjectArray* x) {} void Canonicalizer::do_NewMultiArray (NewMultiArray* x) {} void Canonicalizer::do_Deoptimize (Deoptimize* x) {} void Canonicalizer::do_CheckCast (CheckCast* x) { - if (x->klass()->is_loaded() && !x->klass()->is_inlinetype()) { - // Don't canonicalize for non-nullable types -- we need to throw NPE. + if (x->klass()->is_loaded()) { Value obj = x->obj(); ciType* klass = obj->exact_type(); if (klass == NULL) { @@ -659,12 +658,13 @@ void Canonicalizer::do_CheckCast (CheckCast* x) { // Interface casts can't be statically optimized away since verifier doesn't // enforce interface types in bytecode. if (!is_interface && klass->is_subtype_of(x->klass())) { + assert(!x->klass()->is_inlinetype() || x->klass() == klass, "Inline klasses can't have subtypes"); set_canonical(obj); return; } } - // checkcast of null returns null - if (obj->as_Constant() && obj->type()->as_ObjectType()->constant_value()->is_null_object()) { + // checkcast of null returns null for non-inline klasses + if (!x->klass()->is_inlinetype() && obj->as_Constant() && obj->type()->as_ObjectType()->constant_value()->is_null_object()) { set_canonical(obj); } } diff --git a/src/hotspot/share/c1/c1_GraphBuilder.cpp b/src/hotspot/share/c1/c1_GraphBuilder.cpp index 833ec73b467..cc1179fd511 100644 --- a/src/hotspot/share/c1/c1_GraphBuilder.cpp +++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp @@ -2043,8 +2043,7 @@ void GraphBuilder::access_field(Bytecodes::Code code) { } // Baseline version of withfield, allocate every time -void GraphBuilder::withfield(int field_index) -{ +void GraphBuilder::withfield(int field_index) { // Save the entire state and re-execute on deopt ValueStack* state_before = copy_state_before(); state_before->set_should_reexecute(true); diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java index 98ab9441294..bc02ca0ee92 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestNullableInlineTypes.java @@ -956,4 +956,21 @@ public void test39_verifier(boolean warmup) { res = test39(false, testValue1, testValue1); Asserts.assertEquals(res, testValue1.x); } + + // Test NPE when casting constant null to inline type + @Test() + public MyValue1 test40() throws Throwable { + Object NULL = null; + return (MyValue1)NULL; + } + + @DontCompile + public void test40_verifier(boolean warmup) throws Throwable { + try { + test40(); + throw new RuntimeException("NullPointerException expected"); + } catch (NullPointerException e) { + // Expected + } + } } diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/TestFieldTypeMismatch.java b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/TestFieldTypeMismatch.java index 8efdf957cf7..71474520596 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/TestFieldTypeMismatch.java +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/TestFieldTypeMismatch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -21,7 +21,7 @@ * questions. */ -package compiler.valhalla.inlinetypes; +package runtime.valhalla.inlinetypes; import jdk.test.lib.Asserts; @@ -30,7 +30,7 @@ * @library /test/lib * @compile TestFieldTypeMismatchHelper.jasm * @compile TestFieldTypeMismatch.java - * @run main/othervm compiler.valhalla.inlinetypes.TestFieldTypeMismatch + * @run main/othervm runtime.valhalla.inlinetypes.TestFieldTypeMismatch */ final class MyValue { @@ -46,7 +46,7 @@ public static void main(String[] args) { } catch(IncompatibleClassChangeError err) { exception = true; Asserts.assertEquals(err.getMessage(), - "Class compiler/valhalla/inlinetypes/TestFieldTypeMismatchHelper expects class compiler.valhalla.inlinetypes.MyValue to be an inline type, but it is not"); + "Class runtime/valhalla/inlinetypes/TestFieldTypeMismatchHelper expects class runtime.valhalla.inlinetypes.MyValue to be an inline type, but it is not"); } Asserts.assertTrue(exception); } diff --git a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/TestFieldTypeMismatchHelper.jasm b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/TestFieldTypeMismatchHelper.jasm index 1850e066c04..09adeb3934c 100644 --- a/test/hotspot/jtreg/runtime/valhalla/inlinetypes/TestFieldTypeMismatchHelper.jasm +++ b/test/hotspot/jtreg/runtime/valhalla/inlinetypes/TestFieldTypeMismatchHelper.jasm @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -22,9 +22,9 @@ * */ -public class compiler/valhalla/inlinetypes/TestFieldTypeMismatchHelper version 61:0 { +public class runtime/valhalla/inlinetypes/TestFieldTypeMismatchHelper version 61:0 { - Field field:"Qcompiler/valhalla/inlinetypes/MyValue;"; + Field field:"Qruntime/valhalla/inlinetypes/MyValue;"; public Method "":"()V" stack 1 locals 1 @@ -37,7 +37,7 @@ public class compiler/valhalla/inlinetypes/TestFieldTypeMismatchHelper version 6 public Method test:"()V" stack 2 locals 1 { aload_0; aconst_null; - putfield Field field:"Qcompiler/valhalla/inlinetypes/MyValue;"; + putfield Field field:"Qruntime/valhalla/inlinetypes/MyValue;"; return; } }