jdk

Форк
0
/
FieldDensityTest.java 
157 строк · 4.5 Кб
1
/*
2
 * Copyright (c) 2020, 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 8237767
27
 * @summary Verify behaviour of field layout algorithm
28
 * @library /test/lib
29
 * @modules java.base/jdk.internal.misc
30
 *          java.management
31
 * @run main/othervm FieldDensityTest
32
 */
33

34
/*
35
 * @test
36
 * @requires vm.bits == "64"
37
 * @library /test/lib
38
 * @modules java.base/jdk.internal.misc
39
 *          java.management
40
 * @run main/othervm -XX:+UseCompressedOops -XX:+UseCompressedClassPointers FieldDensityTest
41
 * @run main/othervm -XX:+UseCompressedOops -XX:-UseCompressedClassPointers FieldDensityTest
42
 */
43

44
import java.lang.reflect.Field;
45
import java.util.Arrays;
46
import java.util.Comparator;
47
import jdk.internal.misc.Unsafe;
48

49
import jdk.test.lib.Asserts;
50

51
public class FieldDensityTest {
52

53
    static int OOP_SIZE_IN_BYTES = 0;
54

55
    static {
56
        if (System.getProperty("sun.arch.data.model").equals("64")) {
57
            if (System.getProperty("java.vm.compressedOopsMode") == null) {
58
                OOP_SIZE_IN_BYTES = 8;
59
            } else {
60
                OOP_SIZE_IN_BYTES = 4;
61
            }
62
        } else {
63
            OOP_SIZE_IN_BYTES = 4;
64
        }
65
    }
66

67
    static class FieldInfo {
68
        public Field field;
69
        public long offset;
70

71
        FieldInfo(Field field, long offset) {
72
            this.field = field;
73
            this.offset = offset;
74
        }
75

76
        static void checkFieldsContiguity(FieldInfo[] fieldInfo) {
77
            Arrays.sort(fieldInfo, new SortByOffset());
78
            for (int i = 0 ; i <  fieldInfo.length - 2; i++) {
79
                int size = sizeInBytesFromType(fieldInfo[i].field.getType());
80
                Asserts.assertEquals((int)(fieldInfo[i].offset + size), (int)fieldInfo[i+1].offset,
81
                                     "Empty slot between fields, should not happen");
82
            }
83
        }
84
    }
85

86
    static int sizeInBytesFromType(Class type) {
87
        if (!type.isPrimitive()) {
88
            return OOP_SIZE_IN_BYTES;
89
        }
90
        switch(type.getTypeName()) {
91
        case "boolean":
92
        case "byte": return 1;
93
        case "char":
94
        case "short": return 2;
95
        case "int":
96
        case "float": return 4;
97
        case "long":
98
        case "double": return 8;
99
        default:
100
            throw new RuntimeException("Unrecognized signature");
101
        }
102
    }
103

104
    static class SortByOffset implements Comparator<FieldInfo> {
105
        public int compare(FieldInfo a, FieldInfo b)
106
        {
107
            return (int)(a.offset - b.offset);
108
        }
109
    }
110

111
    static class E {
112
        public byte b0;
113
    }
114

115
    static class F extends E {
116
        public byte b1;
117
    }
118

119
    static class G extends F {
120
        public byte b2;
121
    }
122

123
    static class H extends G {
124
        public byte b3;
125
    }
126

127
    public static class A {
128
        public int i;
129
        public byte b;
130
        public long l;
131
        public Object o;
132
    }
133

134
    public static class B extends A {
135
        public byte b0, b1, b2;
136
    }
137

138
    static void testFieldsContiguity(Class c) {
139
        Unsafe unsafe = Unsafe.getUnsafe();
140
        Field[] fields = c.getFields();
141
        FieldInfo[] fieldsInfo = new FieldInfo[fields.length];
142
        int i = 0;
143
        for (Field f : fields) {
144
            long offset = unsafe.objectFieldOffset(f);
145
            fieldsInfo[i] = new FieldInfo(f, offset);
146
            i++;
147
        }
148
        FieldInfo.checkFieldsContiguity(fieldsInfo);
149
    }
150

151
    public static void main(String[] args) {
152
        H h = new H();
153
        testFieldsContiguity(h.getClass());
154
        B b = new B();
155
        testFieldsContiguity(b.getClass());
156
    }
157
}
158

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.