2
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
25
#include "precompiled.hpp"
26
#include "asm/codeBuffer.hpp"
27
#include "asm/macroAssembler.hpp"
28
#include "opto/block.hpp"
29
#include "opto/constantTable.hpp"
30
#include "opto/machnode.hpp"
31
#include "opto/output.hpp"
33
//=============================================================================
34
// Two Constant's are equal when the type and the value are equal.
35
bool ConstantTable::Constant::operator==(const Constant& other) {
36
if (type() != other.type() ) return false;
37
if (can_be_reused() != other.can_be_reused()) return false;
38
if (is_array() || other.is_array()) {
39
if (is_array() != other.is_array() ||
40
get_array()->length() != other.get_array()->length()) {
43
for (int i = 0; i < get_array()->length(); i++) {
44
jvalue ele1 = get_array()->at(i);
45
jvalue ele2 = other.get_array()->at(i);
48
case T_BOOLEAN: is_eq = ele1.z == ele2.z; break;
49
case T_BYTE: is_eq = ele1.b == ele2.b; break;
50
case T_CHAR: is_eq = ele1.c == ele2.c; break;
51
case T_SHORT: is_eq = ele1.s == ele2.s; break;
52
case T_INT: is_eq = ele1.i == ele2.i; break;
53
case T_LONG: is_eq = ele1.j == ele2.j; break;
54
case T_FLOAT: is_eq = jint_cast(ele1.f) == jint_cast(ele2.f); break;
55
case T_DOUBLE: is_eq = jlong_cast(ele1.d) == jlong_cast(ele2.d); break;
56
default: ShouldNotReachHere(); is_eq = false;
64
// For floating point values we compare the bit pattern.
66
case T_INT: return (_v._value.i == other._v._value.i);
67
case T_FLOAT: return jint_cast(_v._value.f) == jint_cast(other._v._value.f);
68
case T_LONG: return (_v._value.j == other._v._value.j);
69
case T_DOUBLE: return jlong_cast(_v._value.d) == jlong_cast(other._v._value.d);
71
case T_ADDRESS: return (_v._value.l == other._v._value.l);
72
case T_VOID: return (_v._value.l == other._v._value.l); // jump-table entries
73
case T_METADATA: return (_v._metadata == other._v._metadata);
74
default: ShouldNotReachHere(); return false;
78
int ConstantTable::qsort_comparator(Constant* a, Constant* b) {
80
if (a->freq() > b->freq()) return -1;
81
if (a->freq() < b->freq()) return 1;
85
static int constant_size(ConstantTable::Constant* con) {
86
if (con->is_array()) {
87
return type2aelembytes(con->type()) * con->get_array()->length();
89
switch (con->type()) {
90
case T_INT: return sizeof(jint );
91
case T_LONG: return sizeof(jlong );
92
case T_FLOAT: return sizeof(jfloat );
93
case T_DOUBLE: return sizeof(jdouble);
94
case T_METADATA: return sizeof(Metadata*);
95
// We use T_VOID as marker for jump-table entries (labels) which
96
// need an internal word relocation.
99
case T_OBJECT: return sizeof(jobject);
101
ShouldNotReachHere();
106
void ConstantTable::calculate_offsets_and_size() {
107
// First, sort the array by frequencies.
108
_constants.sort(qsort_comparator);
111
// Make sure all jump-table entries were sorted to the end of the
112
// array (they have a negative frequency).
113
bool found_void = false;
114
for (int i = 0; i < _constants.length(); i++) {
115
Constant con = _constants.at(i);
116
if (con.type() == T_VOID)
117
found_void = true; // jump-tables
119
assert(!found_void, "wrong sorting");
124
for (int i = 0; i < _constants.length(); i++) {
125
Constant* con = _constants.adr_at(i);
127
// Align offset for type.
128
int typesize = constant_size(con);
129
assert(typesize <= 8 || con->is_array(), "sanity");
130
offset = align_up(offset, con->alignment());
131
con->set_offset(offset); // set constant's offset
133
if (con->type() == T_VOID) {
134
MachConstantNode* n = (MachConstantNode*) con->get_jobject();
135
offset = offset + typesize * n->outcnt(); // expand jump-table
137
offset = offset + typesize;
141
// Align size up to the next section start (which is insts; see
142
// CodeBuffer::align_at_start).
143
assert(_size == -1, "already set?");
144
_size = align_up(offset, (int)CodeEntryAlignment);
147
bool ConstantTable::emit(C2_MacroAssembler* masm) const {
148
for (int i = 0; i < _constants.length(); i++) {
149
Constant con = _constants.at(i);
150
address constant_addr = nullptr;
151
if (con.is_array()) {
152
constant_addr = masm->array_constant(con.type(), con.get_array(), con.alignment());
154
switch (con.type()) {
155
case T_INT: constant_addr = masm->int_constant( con.get_jint() ); break;
156
case T_LONG: constant_addr = masm->long_constant( con.get_jlong() ); break;
157
case T_FLOAT: constant_addr = masm->float_constant( con.get_jfloat() ); break;
158
case T_DOUBLE: constant_addr = masm->double_constant(con.get_jdouble()); break;
160
jobject obj = con.get_jobject();
161
int oop_index = masm->oop_recorder()->find_index(obj);
162
constant_addr = masm->address_constant((address) obj, oop_Relocation::spec(oop_index));
166
address addr = (address) con.get_jobject();
167
constant_addr = masm->address_constant(addr);
170
// We use T_VOID as marker for jump-table entries (labels) which
171
// need an internal word relocation.
173
MachConstantNode* n = (MachConstantNode*) con.get_jobject();
174
// Fill the jump-table with a dummy word. The real value is
175
// filled in later in fill_jump_table.
176
address dummy = (address) n;
177
constant_addr = masm->address_constant(dummy);
178
if (constant_addr == nullptr) {
181
assert((constant_addr - masm->code()->consts()->start()) == con.offset(),
182
"must be: %d == %d", (int)(constant_addr - masm->code()->consts()->start()), (int)(con.offset()));
185
address last_addr = nullptr;
186
for (uint j = 1; j < n->outcnt(); j++) {
187
last_addr = masm->address_constant(dummy + j);
188
if (last_addr == nullptr) {
193
address start = masm->code()->consts()->start();
194
address new_constant_addr = last_addr - ((n->outcnt() - 1) * sizeof(address));
195
// Expanding the jump-table could result in an expansion of the const code section.
196
// In that case, we need to check if the new constant address matches the offset.
197
assert((constant_addr - start == con.offset()) || (new_constant_addr - start == con.offset()),
198
"must be: %d == %d or %d == %d (after an expansion)", (int)(constant_addr - start), (int)(con.offset()),
199
(int)(new_constant_addr - start), (int)(con.offset()));
204
Metadata* obj = con.get_metadata();
205
int metadata_index = masm->oop_recorder()->find_index(obj);
206
constant_addr = masm->address_constant((address) obj, metadata_Relocation::spec(metadata_index));
209
default: ShouldNotReachHere();
213
if (constant_addr == nullptr) {
216
assert((constant_addr - masm->code()->consts()->start()) == con.offset(),
217
"must be: %d == %d", (int)(constant_addr - masm->code()->consts()->start()), (int)(con.offset()));
222
int ConstantTable::find_offset(Constant& con) const {
223
int idx = _constants.find(con);
224
guarantee(idx != -1, "constant must be in constant table");
225
int offset = _constants.at(idx).offset();
226
guarantee(offset != -1, "constant table not emitted yet?");
230
void ConstantTable::add(Constant& con) {
231
if (con.can_be_reused()) {
232
int idx = _constants.find(con);
233
if (idx != -1 && _constants.at(idx).can_be_reused()) {
234
_constants.adr_at(idx)->inc_freq(con.freq()); // increase the frequency by the current value
238
(void) _constants.append(con);
241
ConstantTable::Constant ConstantTable::add(MachConstantNode* n, BasicType type, jvalue value) {
242
Block* b = Compile::current()->cfg()->get_block_for_node(n);
243
Constant con(type, value, b->_freq);
248
ConstantTable::Constant ConstantTable::add(Metadata* metadata) {
249
Constant con(metadata);
254
ConstantTable::Constant ConstantTable::add(MachConstantNode* n, BasicType bt,
255
GrowableArray<jvalue>* array, int alignment) {
256
Constant con(bt, array, alignment);
261
ConstantTable::Constant ConstantTable::add(MachConstantNode* n, BasicType bt,
262
GrowableArray<jvalue>* array) {
263
return add(n, bt, array, array->length() * type2aelembytes(bt));
266
ConstantTable::Constant ConstantTable::add(MachConstantNode* n, MachOper* oper) {
268
BasicType type = oper->type()->basic_type();
270
case T_LONG: value.j = oper->constantL(); break;
271
case T_INT: value.i = oper->constant(); break;
272
case T_FLOAT: value.f = oper->constantF(); break;
273
case T_DOUBLE: value.d = oper->constantD(); break;
275
case T_ADDRESS: value.l = (jobject) oper->constant(); break;
276
case T_METADATA: return add((Metadata*)oper->constant()); break;
277
default: guarantee(false, "unhandled type: %s", type2name(type));
279
return add(n, type, value);
282
ConstantTable::Constant ConstantTable::add_jump_table(MachConstantNode* n) {
284
// We can use the node pointer here to identify the right jump-table
285
// as this method is called from Compile::Fill_buffer right before
286
// the MachNodes are emitted and the jump-table is filled (means the
287
// MachNode pointers do not change anymore).
288
value.l = (jobject) n;
289
Constant con(T_VOID, value, next_jump_table_freq(), false); // Labels of a jump-table cannot be reused.
294
void ConstantTable::fill_jump_table(C2_MacroAssembler* masm, MachConstantNode* n, GrowableArray<Label*> labels) const {
295
// If called from Compile::scratch_emit_size do nothing.
296
if (Compile::current()->output()->in_scratch_emit_size()) return;
298
assert(labels.is_nonempty(), "must be");
299
assert((uint) labels.length() == n->outcnt(), "must be equal: %d == %d", labels.length(), n->outcnt());
301
// Since MachConstantNode::constant_offset() also contains
302
// table_base_offset() we need to subtract the table_base_offset()
303
// to get the plain offset into the constant table.
304
int offset = n->constant_offset() - table_base_offset();
306
address* jump_table_base = (address*) (masm->code()->consts()->start() + offset);
308
for (uint i = 0; i < n->outcnt(); i++) {
309
address* constant_addr = &jump_table_base[i];
310
assert(*constant_addr == (((address) n) + i), "all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, p2i(*constant_addr), p2i(((address) n) + i));
311
*constant_addr = masm->code()->consts()->target(*labels.at(i), (address) constant_addr);
312
masm->code()->consts()->relocate((address) constant_addr, relocInfo::internal_word_type);