Skip to content

Commit fd81865

Browse files
committed
8273359: CI: ciInstanceKlass::get_canonical_holder() doesn't respect instance size
Backport-of: f7e9f56e235dc50daae0a85c9790d5b04c9c60f0
1 parent 962f393 commit fd81865

File tree

5 files changed

+68
-7
lines changed

5 files changed

+68
-7
lines changed

src/hotspot/share/c1/c1_LIRGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ void LIRGenerator::new_instance(LIR_Opr dst, ciInstanceKlass* klass, bool is_unr
663663

664664
assert(klass->is_loaded(), "must be loaded");
665665
// allocate space for instance
666-
assert(klass->size_helper() >= 0, "illegal instance size");
666+
assert(klass->size_helper() > 0, "illegal instance size");
667667
const int instance_size = align_object_size(klass->size_helper());
668668
__ allocate_object(dst, scratch1, scratch2, scratch3, scratch4,
669669
oopDesc::header_size(), instance_size, klass_reg, !klass->is_initialized(), slow_path);

src/hotspot/share/ci/ciInstanceKlass.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,12 @@ ciConstantPoolCache* ciInstanceKlass::field_cache() {
205205
//
206206
ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) {
207207
#ifdef ASSERT
208-
if (!(offset >= 0 && offset < layout_helper())) {
208+
if (!(offset >= 0 && offset < layout_helper_size_in_bytes())) {
209209
tty->print("*** get_canonical_holder(%d) on ", offset);
210210
this->print();
211211
tty->print_cr(" ***");
212212
};
213-
assert(offset >= 0 && offset < layout_helper(), "offset must be tame");
213+
assert(offset >= 0 && offset < layout_helper_size_in_bytes(), "offset must be tame");
214214
#endif
215215

216216
if (offset < instanceOopDesc::base_offset_in_bytes()) {
@@ -227,7 +227,9 @@ ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) {
227227
for (;;) {
228228
assert(self->is_loaded(), "must be loaded to have size");
229229
ciInstanceKlass* super = self->super();
230-
if (super == NULL || super->nof_nonstatic_fields() == 0) {
230+
if (super == NULL ||
231+
super->nof_nonstatic_fields() == 0 ||
232+
super->layout_helper_size_in_bytes() <= offset) {
231233
return self;
232234
} else {
233235
self = super; // return super->get_canonical_holder(offset)

src/hotspot/share/ci/ciInstanceKlass.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ class ciInstanceKlass : public ciKlass {
165165
return compute_shared_has_subklass();
166166
}
167167

168+
jint layout_helper_size_in_bytes() {
169+
return Klass::layout_helper_size_in_bytes(layout_helper());
170+
}
168171
jint size_helper() {
169172
return (Klass::layout_helper_size_in_bytes(layout_helper())
170173
>> LogHeapWordSize);

src/hotspot/share/opto/compile.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,7 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
13521352
ciInstanceKlass *k = to->klass()->as_instance_klass();
13531353
if( ptr == TypePtr::Constant ) {
13541354
if (to->klass() != ciEnv::current()->Class_klass() ||
1355-
offset < k->size_helper() * wordSize) {
1355+
offset < k->layout_helper_size_in_bytes()) {
13561356
// No constant oop pointers (such as Strings); they alias with
13571357
// unknown strings.
13581358
assert(!is_known_inst, "not scalarizable allocation");
@@ -1376,7 +1376,7 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
13761376
if (!is_known_inst) { // Do it only for non-instance types
13771377
tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset);
13781378
}
1379-
} else if (offset < 0 || offset >= k->size_helper() * wordSize) {
1379+
} else if (offset < 0 || offset >= k->layout_helper_size_in_bytes()) {
13801380
// Static fields are in the space above the normal instance
13811381
// fields in the java.lang.Class instance.
13821382
if (to->klass() != ciEnv::current()->Class_klass()) {
@@ -1386,6 +1386,7 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
13861386
}
13871387
} else {
13881388
ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
1389+
assert(offset < canonical_holder->layout_helper_size_in_bytes(), "");
13891390
if (!k->equals(canonical_holder) || tj->offset() != offset) {
13901391
if( is_known_inst ) {
13911392
tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id());
@@ -1658,7 +1659,7 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr
16581659
ciField* field;
16591660
if (tinst->const_oop() != NULL &&
16601661
tinst->klass() == ciEnv::current()->Class_klass() &&
1661-
tinst->offset() >= (tinst->klass()->as_instance_klass()->size_helper() * wordSize)) {
1662+
tinst->offset() >= (tinst->klass()->as_instance_klass()->layout_helper_size_in_bytes())) {
16621663
// static field
16631664
ciInstanceKlass* k = tinst->const_oop()->as_instance()->java_lang_Class_klass()->as_instance_klass();
16641665
field = k->get_field_by_offset(tinst->offset(), true);
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8273359
27+
*
28+
* @modules java.base/jdk.internal.misc:+open
29+
* @run main/othervm -Xbatch compiler.unsafe.AlignmentGapAccess
30+
*/
31+
32+
package compiler.unsafe;
33+
34+
import jdk.internal.misc.Unsafe;
35+
36+
public class AlignmentGapAccess {
37+
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
38+
39+
static class A { int fa; }
40+
static class B extends A { byte fb; }
41+
42+
static final long FA_OFFSET = UNSAFE.objectFieldOffset(A.class, "fa");
43+
static final long FB_OFFSET = UNSAFE.objectFieldOffset(B.class, "fb");
44+
45+
static int test(B obj) {
46+
return UNSAFE.getInt(obj, FB_OFFSET + 1);
47+
}
48+
49+
public static void main(String[] args) {
50+
for (int i = 0; i < 20_000; i++) {
51+
test(new B());
52+
}
53+
System.out.println("TEST PASSED");
54+
}
55+
}

0 commit comments

Comments
 (0)