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 }