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 #ifndef SHARE_OPTO_CONSTANTTABLE_HPP 26 #define SHARE_OPTO_CONSTANTTABLE_HPP 27 28 #include "utilities/globalDefinitions.hpp" 29 30 class CodeBuffer; 31 class Metadata; 32 class MachConstantNode; 33 class MachOper; 34 35 class ConstantTable { 36 public: 37 // Constant entry of the constant table. 38 class Constant { 39 private: 40 BasicType _type; 41 union { 42 jvalue _value; 43 Metadata* _metadata; 44 } _v; 45 int _offset; // offset of this constant (in bytes) relative to the constant table base. 46 float _freq; 47 bool _can_be_reused; // true (default) if the value can be shared with other users. 48 49 public: Constant()50 Constant() : _type(T_ILLEGAL), _offset(-1), _freq(0.0f), _can_be_reused(true) { _v._value.l = 0; } Constant(BasicType type,jvalue value,float freq=0.0f,bool can_be_reused=true)51 Constant(BasicType type, jvalue value, float freq = 0.0f, bool can_be_reused = true) : 52 _type(type), 53 _offset(-1), 54 _freq(freq), 55 _can_be_reused(can_be_reused) 56 { 57 assert(type != T_METADATA, "wrong constructor"); 58 _v._value = value; 59 } Constant(Metadata * metadata,bool can_be_reused=true)60 Constant(Metadata* metadata, bool can_be_reused = true) : 61 _type(T_METADATA), 62 _offset(-1), 63 _freq(0.0f), 64 _can_be_reused(can_be_reused) 65 { 66 _v._metadata = metadata; 67 } 68 69 bool operator==(const Constant& other); 70 type() const71 BasicType type() const { return _type; } 72 get_jint() const73 jint get_jint() const { return _v._value.i; } get_jlong() const74 jlong get_jlong() const { return _v._value.j; } get_jfloat() const75 jfloat get_jfloat() const { return _v._value.f; } get_jdouble() const76 jdouble get_jdouble() const { return _v._value.d; } get_jobject() const77 jobject get_jobject() const { return _v._value.l; } 78 get_metadata() const79 Metadata* get_metadata() const { return _v._metadata; } 80 offset() const81 int offset() const { return _offset; } set_offset(int offset)82 void set_offset(int offset) { _offset = offset; } 83 freq() const84 float freq() const { return _freq; } inc_freq(float freq)85 void inc_freq(float freq) { _freq += freq; } 86 can_be_reused() const87 bool can_be_reused() const { return _can_be_reused; } 88 }; 89 90 private: 91 GrowableArray<Constant> _constants; // Constants of this table. 92 int _size; // Size in bytes the emitted constant table takes (including padding). 93 int _table_base_offset; // Offset of the table base that gets added to the constant offsets. 94 int _nof_jump_tables; // Number of jump-tables in this constant table. 95 96 static int qsort_comparator(Constant* a, Constant* b); 97 98 // We use negative frequencies to keep the order of the 99 // jump-tables in which they were added. Otherwise we get into 100 // trouble with relocation. next_jump_table_freq()101 float next_jump_table_freq() { return -1.0f * (++_nof_jump_tables); } 102 103 public: ConstantTable()104 ConstantTable() : 105 _size(-1), 106 _table_base_offset(-1), // We can use -1 here since the constant table is always bigger than 2 bytes (-(size / 2), see MachConstantBaseNode::emit). 107 _nof_jump_tables(0) 108 {} 109 size() const110 int size() const { assert(_size != -1, "not calculated yet"); return _size; } 111 112 int calculate_table_base_offset() const; // AD specific set_table_base_offset(int x)113 void set_table_base_offset(int x) { assert(_table_base_offset == -1 || x == _table_base_offset, "can't change"); _table_base_offset = x; } table_base_offset() const114 int table_base_offset() const { assert(_table_base_offset != -1, "not set yet"); return _table_base_offset; } 115 116 bool emit(CodeBuffer& cb) const; 117 118 // Returns the offset of the last entry (the top) of the constant table. top_offset() const119 int top_offset() const { assert(_constants.top().offset() != -1, "not bound yet"); return _constants.top().offset(); } 120 121 void calculate_offsets_and_size(); 122 int find_offset(Constant& con) const; 123 124 void add(Constant& con); 125 Constant add(MachConstantNode* n, BasicType type, jvalue value); 126 Constant add(Metadata* metadata); 127 Constant add(MachConstantNode* n, MachOper* oper); add(MachConstantNode * n,jint i)128 Constant add(MachConstantNode* n, jint i) { 129 jvalue value; value.i = i; 130 return add(n, T_INT, value); 131 } add(MachConstantNode * n,jlong j)132 Constant add(MachConstantNode* n, jlong j) { 133 jvalue value; value.j = j; 134 return add(n, T_LONG, value); 135 } add(MachConstantNode * n,jfloat f)136 Constant add(MachConstantNode* n, jfloat f) { 137 jvalue value; value.f = f; 138 return add(n, T_FLOAT, value); 139 } add(MachConstantNode * n,jdouble d)140 Constant add(MachConstantNode* n, jdouble d) { 141 jvalue value; value.d = d; 142 return add(n, T_DOUBLE, value); 143 } 144 145 // Jump-table 146 Constant add_jump_table(MachConstantNode* n); 147 void fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const; 148 }; 149 150 151 #endif // SHARE_OPTO_CONSTANTTABLE_HPP 152