Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/aarch32/vm/jniFastGetField_aarch32.cpp
32285 views
1
/*
2
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
4
* Copyright (c) 2015, Linaro Ltd. All rights reserved.
5
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6
*
7
* This code is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License version 2 only, as
9
* published by the Free Software Foundation.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*
25
*/
26
27
#include "precompiled.hpp"
28
#include "asm/macroAssembler.hpp"
29
#include "memory/resourceArea.hpp"
30
#include "prims/jniFastGetField.hpp"
31
#include "prims/jvm_misc.hpp"
32
#include "runtime/safepoint.hpp"
33
34
#define __ masm->
35
36
#define BUFFER_SIZE_ARMV7 31*wordSize
37
#define BUFFER_SIZE_ARMV6 51*wordSize
38
39
// Instead of issuing a LoadLoad barrier we create an address
40
// dependency between loads; this might be more efficient.
41
42
// Common register usage:
43
// r0/v0: result
44
// c_rarg0: jni env
45
// c_rarg1: obj
46
// c_rarg2: jfield id
47
48
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
49
Register result = c_rarg0;
50
Register robj = c_rarg1;
51
Register rcounter = c_rarg3;
52
int args = RegSet::of(c_rarg0, c_rarg1, c_rarg2).bits();
53
int nargs = 3;
54
55
const char *name;
56
switch (type) {
57
case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
58
case T_BYTE: name = "jni_fast_GetByteField"; break;
59
case T_CHAR: name = "jni_fast_GetCharField"; break;
60
case T_SHORT: name = "jni_fast_GetShortField"; break;
61
case T_INT: name = "jni_fast_GetIntField"; break;
62
case T_LONG: name = "jni_fast_GetLongField"; break;
63
case T_FLOAT: name = "jni_fast_GetFloatField"; break;
64
case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
65
default: ShouldNotReachHere();
66
}
67
ResourceMark rm;
68
BufferBlob* blob = BufferBlob::create(name,
69
VM_Version::features() & FT_ARMV7 ?
70
BUFFER_SIZE_ARMV7 :
71
BUFFER_SIZE_ARMV6 );
72
CodeBuffer cbuf(blob);
73
MacroAssembler* masm = new MacroAssembler(&cbuf);
74
address fast_entry = __ pc();
75
76
Label slow;
77
78
__ lea(rcounter, SafepointSynchronize::safepoint_counter_addr());
79
__ ldr(rcounter, rcounter);
80
__ tst(rcounter, 1);
81
__ b(slow, Assembler::NE);
82
__ stmdb(sp, args);
83
// doesn't change c_rarg1 but does force a dependency on rcounter before
84
// performing __ ldr(robj, ...
85
__ eor(robj, c_rarg1, rcounter);
86
__ eor(robj, robj, rcounter);
87
88
__ clear_jweak_tag(robj);
89
90
__ ldr(robj, Address(robj, 0)); // *obj
91
92
assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
93
speculative_load_pclist[count] = __ pc(); // Used by the segfault handler
94
// c_rarg2 * 2 is offset
95
// Only ldr & ldrb support shifted loads
96
switch (type) {
97
case T_FLOAT:
98
case T_INT: __ ldr (result, Address(robj, c_rarg2, lsr(2))); break;
99
case T_BOOLEAN: __ ldrb(result, Address(robj, c_rarg2, lsr(2))); break;
100
default: {
101
__ lsr(c_rarg2, c_rarg2, 2);
102
switch(type) {
103
case T_BYTE: __ ldrsb (result, Address(robj, c_rarg2)); break;
104
case T_CHAR: __ ldrh (result, Address(robj, c_rarg2)); break;
105
case T_SHORT: __ ldrsh (result, Address(robj, c_rarg2)); break;
106
case T_DOUBLE:
107
case T_LONG: __ ldrd (result, Address(robj, c_rarg2)); break;
108
default: ShouldNotReachHere();
109
}
110
}
111
}
112
__ lea(rscratch2, SafepointSynchronize::safepoint_counter_addr());
113
// rscratch2 is address dependent on result.
114
// TODO Do we need to force dependency on r1 too?
115
__ eor(rscratch2, rscratch2, result);
116
__ eor(rscratch2, rscratch2, result);
117
__ ldr(rscratch2, rscratch2);
118
__ cmp(rcounter, rscratch2);
119
120
#ifdef HARD_FLOAT_CC
121
switch (type) {
122
case T_FLOAT: __ vmov_f32(d0, result, Assembler::EQ); break;
123
case T_DOUBLE: __ vmov_f64(d0, r0, r1, Assembler::EQ); break; // Change me if result changes
124
default: break;
125
}
126
#endif//HARD_FLOAT_CC
127
128
__ add(sp, sp, nargs * wordSize, Assembler::EQ); // Pop args if we don't need them.
129
__ b(lr, Assembler::EQ);
130
131
// Restore args for slowcase call into the vm
132
__ ldmia(sp, args);
133
134
// Slowcase
135
slowcase_entry_pclist[count++] = __ pc();
136
__ bind(slow);
137
138
address slow_case_addr = NULL;
139
switch (type) {
140
case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
141
case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
142
case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;
143
case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;
144
case T_INT: slow_case_addr = jni_GetIntField_addr(); break;
145
case T_LONG: slow_case_addr = jni_GetLongField_addr(); break;
146
case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
147
case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
148
default: ShouldNotReachHere();
149
}
150
151
{
152
__ enter();
153
__ lea(rscratch2, ExternalAddress(slow_case_addr));
154
__ bl(rscratch2);
155
__ maybe_isb();
156
__ leave();
157
__ b(lr);
158
}
159
__ flush ();
160
161
return fast_entry;
162
}
163
164
address JNI_FastGetField::generate_fast_get_boolean_field() {
165
return generate_fast_get_int_field0(T_BOOLEAN);
166
}
167
168
address JNI_FastGetField::generate_fast_get_byte_field() {
169
return generate_fast_get_int_field0(T_BYTE);
170
}
171
172
address JNI_FastGetField::generate_fast_get_char_field() {
173
return generate_fast_get_int_field0(T_CHAR);
174
}
175
176
address JNI_FastGetField::generate_fast_get_short_field() {
177
return generate_fast_get_int_field0(T_SHORT);
178
}
179
180
address JNI_FastGetField::generate_fast_get_int_field() {
181
return generate_fast_get_int_field0(T_INT);
182
}
183
184
address JNI_FastGetField::generate_fast_get_long_field() {
185
return generate_fast_get_int_field0(T_LONG);
186
}
187
188
address JNI_FastGetField::generate_fast_get_float_field() {
189
return generate_fast_get_int_field0(T_FLOAT);
190
}
191
192
address JNI_FastGetField::generate_fast_get_double_field() {
193
return generate_fast_get_int_field0(T_DOUBLE);
194
}
195
196
197