Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit a7a603c

Browse files
author
Yuri Nesterenko
committed
8273359: CI: ciInstanceKlass::get_canonical_holder() doesn't respect instance size
Reviewed-by: bae Backport-of: f7e9f56e235dc50daae0a85c9790d5b04c9c60f0
1 parent d7fbb0b commit a7a603c

File tree

5 files changed

+69
-7
lines changed

5 files changed

+69
-7
lines changed

src/hotspot/share/c1/c1_LIRGenerator.cpp

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

681681
assert(klass->is_loaded(), "must be loaded");
682682
// allocate space for instance
683-
assert(klass->size_helper() >= 0, "illegal instance size");
683+
assert(klass->size_helper() > 0, "illegal instance size");
684684
const int instance_size = align_object_size(klass->size_helper());
685685
__ allocate_object(dst, scratch1, scratch2, scratch3, scratch4,
686686
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
@@ -203,12 +203,12 @@ ciConstantPoolCache* ciInstanceKlass::field_cache() {
203203
//
204204
ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) {
205205
#ifdef ASSERT
206-
if (!(offset >= 0 && offset < layout_helper())) {
206+
if (!(offset >= 0 && offset < layout_helper_size_in_bytes())) {
207207
tty->print("*** get_canonical_holder(%d) on ", offset);
208208
this->print();
209209
tty->print_cr(" ***");
210210
};
211-
assert(offset >= 0 && offset < layout_helper(), "offset must be tame");
211+
assert(offset >= 0 && offset < layout_helper_size_in_bytes(), "offset must be tame");
212212
#endif
213213

214214
if (offset < instanceOopDesc::base_offset_in_bytes()) {
@@ -225,7 +225,9 @@ ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) {
225225
for (;;) {
226226
assert(self->is_loaded(), "must be loaded to have size");
227227
ciInstanceKlass* super = self->super();
228-
if (super == NULL || super->nof_nonstatic_fields() == 0) {
228+
if (super == NULL ||
229+
super->nof_nonstatic_fields() == 0 ||
230+
super->layout_helper_size_in_bytes() <= offset) {
229231
return self;
230232
} else {
231233
self = super; // return super->get_canonical_holder(offset)

src/hotspot/share/ci/ciInstanceKlass.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ class ciInstanceKlass : public ciKlass {
162162
}
163163
return _has_subklass == subklass_true;
164164
}
165+
166+
jint layout_helper_size_in_bytes() {
167+
return Klass::layout_helper_size_in_bytes(layout_helper());
168+
}
165169
jint size_helper() {
166170
return (Klass::layout_helper_size_in_bytes(layout_helper())
167171
>> LogHeapWordSize);

src/hotspot/share/opto/compile.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,7 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
13161316
ciInstanceKlass *k = to->klass()->as_instance_klass();
13171317
if( ptr == TypePtr::Constant ) {
13181318
if (to->klass() != ciEnv::current()->Class_klass() ||
1319-
offset < k->size_helper() * wordSize) {
1319+
offset < k->layout_helper_size_in_bytes()) {
13201320
// No constant oop pointers (such as Strings); they alias with
13211321
// unknown strings.
13221322
assert(!is_known_inst, "not scalarizable allocation");
@@ -1340,7 +1340,7 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
13401340
if (!is_known_inst) { // Do it only for non-instance types
13411341
tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset);
13421342
}
1343-
} else if (offset < 0 || offset >= k->size_helper() * wordSize) {
1343+
} else if (offset < 0 || offset >= k->layout_helper_size_in_bytes()) {
13441344
// Static fields are in the space above the normal instance
13451345
// fields in the java.lang.Class instance.
13461346
if (to->klass() != ciEnv::current()->Class_klass()) {
@@ -1350,6 +1350,7 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
13501350
}
13511351
} else {
13521352
ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
1353+
assert(offset < canonical_holder->layout_helper_size_in_bytes(), "");
13531354
if (!k->equals(canonical_holder) || tj->offset() != offset) {
13541355
if( is_known_inst ) {
13551356
tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id());
@@ -1622,7 +1623,7 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr
16221623
ciField* field;
16231624
if (tinst->const_oop() != NULL &&
16241625
tinst->klass() == ciEnv::current()->Class_klass() &&
1625-
tinst->offset() >= (tinst->klass()->as_instance_klass()->size_helper() * wordSize)) {
1626+
tinst->offset() >= (tinst->klass()->as_instance_klass()->layout_helper_size_in_bytes())) {
16261627
// static field
16271628
ciInstanceKlass* k = tinst->const_oop()->as_instance()->java_lang_Class_klass()->as_instance_klass();
16281629
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)