Mercurial > hg > graal-compiler
comparison src/share/vm/opto/compile.cpp @ 4114:6729bbc1fcd6
7003454: order constants in constant table by number of references in code
Reviewed-by: kvn, never, bdelsart
author | twisti |
---|---|
date | Wed, 16 Nov 2011 01:39:50 -0800 |
parents | 670a74b863fc |
children | 1bd45abaa507 |
comparison
equal
deleted
inserted
replaced
4113:8c57262447d3 | 4114:6729bbc1fcd6 |
---|---|
3050 default: ShouldNotReachHere(); | 3050 default: ShouldNotReachHere(); |
3051 } | 3051 } |
3052 return false; | 3052 return false; |
3053 } | 3053 } |
3054 | 3054 |
3055 // Emit constants grouped in the following order: | |
3056 static BasicType type_order[] = { | |
3057 T_FLOAT, // 32-bit | |
3058 T_OBJECT, // 32 or 64-bit | |
3059 T_ADDRESS, // 32 or 64-bit | |
3060 T_DOUBLE, // 64-bit | |
3061 T_LONG, // 64-bit | |
3062 T_VOID, // 32 or 64-bit (jump-tables are at the end of the constant table for code emission reasons) | |
3063 T_ILLEGAL | |
3064 }; | |
3065 | |
3066 static int type_to_size_in_bytes(BasicType t) { | 3055 static int type_to_size_in_bytes(BasicType t) { |
3067 switch (t) { | 3056 switch (t) { |
3068 case T_LONG: return sizeof(jlong ); | 3057 case T_LONG: return sizeof(jlong ); |
3069 case T_FLOAT: return sizeof(jfloat ); | 3058 case T_FLOAT: return sizeof(jfloat ); |
3070 case T_DOUBLE: return sizeof(jdouble); | 3059 case T_DOUBLE: return sizeof(jdouble); |
3071 // We use T_VOID as marker for jump-table entries (labels) which | 3060 // We use T_VOID as marker for jump-table entries (labels) which |
3072 // need an interal word relocation. | 3061 // need an internal word relocation. |
3073 case T_VOID: | 3062 case T_VOID: |
3074 case T_ADDRESS: | 3063 case T_ADDRESS: |
3075 case T_OBJECT: return sizeof(jobject); | 3064 case T_OBJECT: return sizeof(jobject); |
3076 } | 3065 } |
3077 | 3066 |
3078 ShouldNotReachHere(); | 3067 ShouldNotReachHere(); |
3079 return -1; | 3068 return -1; |
3080 } | 3069 } |
3081 | 3070 |
3071 int Compile::ConstantTable::qsort_comparator(Constant* a, Constant* b) { | |
3072 // sort descending | |
3073 if (a->freq() > b->freq()) return -1; | |
3074 if (a->freq() < b->freq()) return 1; | |
3075 return 0; | |
3076 } | |
3077 | |
3082 void Compile::ConstantTable::calculate_offsets_and_size() { | 3078 void Compile::ConstantTable::calculate_offsets_and_size() { |
3083 int size = 0; | 3079 // First, sort the array by frequencies. |
3084 for (int t = 0; type_order[t] != T_ILLEGAL; t++) { | 3080 _constants.sort(qsort_comparator); |
3085 BasicType type = type_order[t]; | 3081 |
3086 | 3082 #ifdef ASSERT |
3087 for (int i = 0; i < _constants.length(); i++) { | 3083 // Make sure all jump-table entries were sorted to the end of the |
3088 Constant con = _constants.at(i); | 3084 // array (they have a negative frequency). |
3089 if (con.type() != type) continue; // Skip other types. | 3085 bool found_void = false; |
3090 | 3086 for (int i = 0; i < _constants.length(); i++) { |
3091 // Align size for type. | 3087 Constant con = _constants.at(i); |
3092 int typesize = type_to_size_in_bytes(con.type()); | 3088 if (con.type() == T_VOID) |
3093 size = align_size_up(size, typesize); | 3089 found_void = true; // jump-tables |
3094 | 3090 else |
3095 // Set offset. | 3091 assert(!found_void, "wrong sorting"); |
3096 con.set_offset(size); | 3092 } |
3097 _constants.at_put(i, con); | 3093 #endif |
3098 | 3094 |
3099 // Add type size. | 3095 int offset = 0; |
3100 size = size + typesize; | 3096 for (int i = 0; i < _constants.length(); i++) { |
3097 Constant* con = _constants.adr_at(i); | |
3098 | |
3099 // Align offset for type. | |
3100 int typesize = type_to_size_in_bytes(con->type()); | |
3101 offset = align_size_up(offset, typesize); | |
3102 con->set_offset(offset); // set constant's offset | |
3103 | |
3104 if (con->type() == T_VOID) { | |
3105 MachConstantNode* n = (MachConstantNode*) con->get_jobject(); | |
3106 offset = offset + typesize * n->outcnt(); // expand jump-table | |
3107 } else { | |
3108 offset = offset + typesize; | |
3101 } | 3109 } |
3102 } | 3110 } |
3103 | 3111 |
3104 // Align size up to the next section start (which is insts; see | 3112 // Align size up to the next section start (which is insts; see |
3105 // CodeBuffer::align_at_start). | 3113 // CodeBuffer::align_at_start). |
3106 assert(_size == -1, "already set?"); | 3114 assert(_size == -1, "already set?"); |
3107 _size = align_size_up(size, CodeEntryAlignment); | 3115 _size = align_size_up(offset, CodeEntryAlignment); |
3108 | |
3109 if (Matcher::constant_table_absolute_addressing) { | |
3110 set_table_base_offset(0); // No table base offset required | |
3111 } else { | |
3112 if (UseRDPCForConstantTableBase) { | |
3113 // table base offset is set in MachConstantBaseNode::emit | |
3114 } else { | |
3115 // When RDPC is not used, the table base is set into the middle of | |
3116 // the constant table. | |
3117 int half_size = _size / 2; | |
3118 assert(half_size * 2 == _size, "sanity"); | |
3119 set_table_base_offset(-half_size); | |
3120 } | |
3121 } | |
3122 } | 3116 } |
3123 | 3117 |
3124 void Compile::ConstantTable::emit(CodeBuffer& cb) { | 3118 void Compile::ConstantTable::emit(CodeBuffer& cb) { |
3125 MacroAssembler _masm(&cb); | 3119 MacroAssembler _masm(&cb); |
3126 for (int t = 0; type_order[t] != T_ILLEGAL; t++) { | 3120 for (int i = 0; i < _constants.length(); i++) { |
3127 BasicType type = type_order[t]; | 3121 Constant con = _constants.at(i); |
3128 | 3122 address constant_addr; |
3129 for (int i = 0; i < _constants.length(); i++) { | 3123 switch (con.type()) { |
3130 Constant con = _constants.at(i); | 3124 case T_LONG: constant_addr = _masm.long_constant( con.get_jlong() ); break; |
3131 if (con.type() != type) continue; // Skip other types. | 3125 case T_FLOAT: constant_addr = _masm.float_constant( con.get_jfloat() ); break; |
3132 | 3126 case T_DOUBLE: constant_addr = _masm.double_constant(con.get_jdouble()); break; |
3133 address constant_addr; | 3127 case T_OBJECT: { |
3134 switch (con.type()) { | 3128 jobject obj = con.get_jobject(); |
3135 case T_LONG: constant_addr = _masm.long_constant( con.get_jlong() ); break; | 3129 int oop_index = _masm.oop_recorder()->find_index(obj); |
3136 case T_FLOAT: constant_addr = _masm.float_constant( con.get_jfloat() ); break; | 3130 constant_addr = _masm.address_constant((address) obj, oop_Relocation::spec(oop_index)); |
3137 case T_DOUBLE: constant_addr = _masm.double_constant(con.get_jdouble()); break; | 3131 break; |
3138 case T_OBJECT: { | 3132 } |
3139 jobject obj = con.get_jobject(); | 3133 case T_ADDRESS: { |
3140 int oop_index = _masm.oop_recorder()->find_index(obj); | 3134 address addr = (address) con.get_jobject(); |
3141 constant_addr = _masm.address_constant((address) obj, oop_Relocation::spec(oop_index)); | 3135 constant_addr = _masm.address_constant(addr); |
3142 break; | 3136 break; |
3143 } | 3137 } |
3144 case T_ADDRESS: { | 3138 // We use T_VOID as marker for jump-table entries (labels) which |
3145 address addr = (address) con.get_jobject(); | 3139 // need an internal word relocation. |
3146 constant_addr = _masm.address_constant(addr); | 3140 case T_VOID: { |
3147 break; | 3141 MachConstantNode* n = (MachConstantNode*) con.get_jobject(); |
3148 } | 3142 // Fill the jump-table with a dummy word. The real value is |
3149 // We use T_VOID as marker for jump-table entries (labels) which | 3143 // filled in later in fill_jump_table. |
3150 // need an interal word relocation. | 3144 address dummy = (address) n; |
3151 case T_VOID: { | 3145 constant_addr = _masm.address_constant(dummy); |
3152 // Write a dummy word. The real value is filled in later | 3146 // Expand jump-table |
3153 // in fill_jump_table_in_constant_table. | 3147 for (uint i = 1; i < n->outcnt(); i++) { |
3154 address addr = (address) con.get_jobject(); | 3148 address temp_addr = _masm.address_constant(dummy + i); |
3155 constant_addr = _masm.address_constant(addr); | 3149 assert(temp_addr, "consts section too small"); |
3156 break; | 3150 } |
3157 } | 3151 break; |
3158 default: ShouldNotReachHere(); | 3152 } |
3159 } | 3153 default: ShouldNotReachHere(); |
3160 assert(constant_addr != NULL, "consts section too small"); | 3154 } |
3161 assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset())); | 3155 assert(constant_addr, "consts section too small"); |
3162 } | 3156 assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset())); |
3163 } | 3157 } |
3164 } | 3158 } |
3165 | 3159 |
3166 int Compile::ConstantTable::find_offset(Constant& con) const { | 3160 int Compile::ConstantTable::find_offset(Constant& con) const { |
3167 int idx = _constants.find(con); | 3161 int idx = _constants.find(con); |
3173 | 3167 |
3174 void Compile::ConstantTable::add(Constant& con) { | 3168 void Compile::ConstantTable::add(Constant& con) { |
3175 if (con.can_be_reused()) { | 3169 if (con.can_be_reused()) { |
3176 int idx = _constants.find(con); | 3170 int idx = _constants.find(con); |
3177 if (idx != -1 && _constants.at(idx).can_be_reused()) { | 3171 if (idx != -1 && _constants.at(idx).can_be_reused()) { |
3172 _constants.adr_at(idx)->inc_freq(con.freq()); // increase the frequency by the current value | |
3178 return; | 3173 return; |
3179 } | 3174 } |
3180 } | 3175 } |
3181 (void) _constants.append(con); | 3176 (void) _constants.append(con); |
3182 } | 3177 } |
3183 | 3178 |
3184 Compile::Constant Compile::ConstantTable::add(BasicType type, jvalue value) { | 3179 Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, BasicType type, jvalue value) { |
3185 Constant con(type, value); | 3180 Block* b = Compile::current()->cfg()->_bbs[n->_idx]; |
3181 Constant con(type, value, b->_freq); | |
3186 add(con); | 3182 add(con); |
3187 return con; | 3183 return con; |
3188 } | 3184 } |
3189 | 3185 |
3190 Compile::Constant Compile::ConstantTable::add(MachOper* oper) { | 3186 Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, MachOper* oper) { |
3191 jvalue value; | 3187 jvalue value; |
3192 BasicType type = oper->type()->basic_type(); | 3188 BasicType type = oper->type()->basic_type(); |
3193 switch (type) { | 3189 switch (type) { |
3194 case T_LONG: value.j = oper->constantL(); break; | 3190 case T_LONG: value.j = oper->constantL(); break; |
3195 case T_FLOAT: value.f = oper->constantF(); break; | 3191 case T_FLOAT: value.f = oper->constantF(); break; |
3196 case T_DOUBLE: value.d = oper->constantD(); break; | 3192 case T_DOUBLE: value.d = oper->constantD(); break; |
3197 case T_OBJECT: | 3193 case T_OBJECT: |
3198 case T_ADDRESS: value.l = (jobject) oper->constant(); break; | 3194 case T_ADDRESS: value.l = (jobject) oper->constant(); break; |
3199 default: ShouldNotReachHere(); | 3195 default: ShouldNotReachHere(); |
3200 } | 3196 } |
3201 return add(type, value); | 3197 return add(n, type, value); |
3202 } | 3198 } |
3203 | 3199 |
3204 Compile::Constant Compile::ConstantTable::allocate_jump_table(MachConstantNode* n) { | 3200 Compile::Constant Compile::ConstantTable::add_jump_table(MachConstantNode* n) { |
3205 jvalue value; | 3201 jvalue value; |
3206 // We can use the node pointer here to identify the right jump-table | 3202 // We can use the node pointer here to identify the right jump-table |
3207 // as this method is called from Compile::Fill_buffer right before | 3203 // as this method is called from Compile::Fill_buffer right before |
3208 // the MachNodes are emitted and the jump-table is filled (means the | 3204 // the MachNodes are emitted and the jump-table is filled (means the |
3209 // MachNode pointers do not change anymore). | 3205 // MachNode pointers do not change anymore). |
3210 value.l = (jobject) n; | 3206 value.l = (jobject) n; |
3211 Constant con(T_VOID, value, false); // Labels of a jump-table cannot be reused. | 3207 Constant con(T_VOID, value, next_jump_table_freq(), false); // Labels of a jump-table cannot be reused. |
3212 for (uint i = 0; i < n->outcnt(); i++) { | 3208 add(con); |
3213 add(con); | |
3214 } | |
3215 return con; | 3209 return con; |
3216 } | 3210 } |
3217 | 3211 |
3218 void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const { | 3212 void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const { |
3219 // If called from Compile::scratch_emit_size do nothing. | 3213 // If called from Compile::scratch_emit_size do nothing. |
3228 int offset = n->constant_offset() - table_base_offset(); | 3222 int offset = n->constant_offset() - table_base_offset(); |
3229 | 3223 |
3230 MacroAssembler _masm(&cb); | 3224 MacroAssembler _masm(&cb); |
3231 address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset); | 3225 address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset); |
3232 | 3226 |
3233 for (int i = 0; i < labels.length(); i++) { | 3227 for (uint i = 0; i < n->outcnt(); i++) { |
3234 address* constant_addr = &jump_table_base[i]; | 3228 address* constant_addr = &jump_table_base[i]; |
3235 assert(*constant_addr == (address) n, "all jump-table entries must contain node pointer"); | 3229 assert(*constant_addr == (((address) n) + i), err_msg("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, *constant_addr, (((address) n) + i))); |
3236 *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr); | 3230 *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr); |
3237 cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type); | 3231 cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type); |
3238 } | 3232 } |
3239 } | 3233 } |