1.1 --- a/src/share/vm/ci/ciMethodData.cpp Mon Jan 27 13:14:53 2014 +0100 1.2 +++ b/src/share/vm/ci/ciMethodData.cpp Tue Feb 25 18:16:24 2014 +0100 1.3 @@ -78,6 +78,35 @@ 1.4 _parameters = NULL; 1.5 } 1.6 1.7 +void ciMethodData::load_extra_data() { 1.8 + MethodData* mdo = get_MethodData(); 1.9 + 1.10 + // speculative trap entries also hold a pointer to a Method so need to be translated 1.11 + DataLayout* dp_src = mdo->extra_data_base(); 1.12 + DataLayout* end_src = mdo->extra_data_limit(); 1.13 + DataLayout* dp_dst = extra_data_base(); 1.14 + for (;; dp_src = MethodData::next_extra(dp_src), dp_dst = MethodData::next_extra(dp_dst)) { 1.15 + assert(dp_src < end_src, "moved past end of extra data"); 1.16 + assert(dp_src->tag() == dp_dst->tag(), err_msg("should be same tags %d != %d", dp_src->tag(), dp_dst->tag())); 1.17 + switch(dp_src->tag()) { 1.18 + case DataLayout::speculative_trap_data_tag: { 1.19 + ciSpeculativeTrapData* data_dst = new ciSpeculativeTrapData(dp_dst); 1.20 + SpeculativeTrapData* data_src = new SpeculativeTrapData(dp_src); 1.21 + data_dst->translate_from(data_src); 1.22 + break; 1.23 + } 1.24 + case DataLayout::bit_data_tag: 1.25 + break; 1.26 + case DataLayout::no_tag: 1.27 + case DataLayout::arg_info_data_tag: 1.28 + // An empty slot or ArgInfoData entry marks the end of the trap data 1.29 + return; 1.30 + default: 1.31 + fatal(err_msg("bad tag = %d", dp_src->tag())); 1.32 + } 1.33 + } 1.34 +} 1.35 + 1.36 void ciMethodData::load_data() { 1.37 MethodData* mdo = get_MethodData(); 1.38 if (mdo == NULL) { 1.39 @@ -116,6 +145,8 @@ 1.40 parameters->translate_from(mdo->parameters_type_data()); 1.41 } 1.42 1.43 + load_extra_data(); 1.44 + 1.45 // Note: Extra data are all BitData, and do not need translation. 1.46 _current_mileage = MethodData::mileage_of(mdo->method()); 1.47 _invocation_counter = mdo->invocation_count(); 1.48 @@ -156,6 +187,12 @@ 1.49 set_type(translate_klass(k)); 1.50 } 1.51 1.52 +void ciSpeculativeTrapData::translate_from(const ProfileData* data) { 1.53 + Method* m = data->as_SpeculativeTrapData()->method(); 1.54 + ciMethod* ci_m = CURRENT_ENV->get_method(m); 1.55 + set_method(ci_m); 1.56 +} 1.57 + 1.58 // Get the data at an arbitrary (sort of) data index. 1.59 ciProfileData* ciMethodData::data_at(int data_index) { 1.60 if (out_of_bounds(data_index)) { 1.61 @@ -203,33 +240,65 @@ 1.62 return next; 1.63 } 1.64 1.65 -// Translate a bci to its corresponding data, or NULL. 1.66 -ciProfileData* ciMethodData::bci_to_data(int bci) { 1.67 - ciProfileData* data = data_before(bci); 1.68 - for ( ; is_valid(data); data = next_data(data)) { 1.69 - if (data->bci() == bci) { 1.70 - set_hint_di(dp_to_di(data->dp())); 1.71 - return data; 1.72 - } else if (data->bci() > bci) { 1.73 - break; 1.74 - } 1.75 - } 1.76 +ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots) { 1.77 // bci_to_extra_data(bci) ... 1.78 DataLayout* dp = data_layout_at(data_size()); 1.79 DataLayout* end = data_layout_at(data_size() + extra_data_size()); 1.80 - for (; dp < end; dp = MethodData::next_extra(dp)) { 1.81 - if (dp->tag() == DataLayout::no_tag) { 1.82 + two_free_slots = false; 1.83 + for (;dp < end; dp = MethodData::next_extra(dp)) { 1.84 + switch(dp->tag()) { 1.85 + case DataLayout::no_tag: 1.86 _saw_free_extra_data = true; // observed an empty slot (common case) 1.87 + two_free_slots = (MethodData::next_extra(dp)->tag() == DataLayout::no_tag); 1.88 return NULL; 1.89 + case DataLayout::arg_info_data_tag: 1.90 + return NULL; // ArgInfoData is at the end of extra data section. 1.91 + case DataLayout::bit_data_tag: 1.92 + if (m == NULL && dp->bci() == bci) { 1.93 + return new ciBitData(dp); 1.94 + } 1.95 + break; 1.96 + case DataLayout::speculative_trap_data_tag: { 1.97 + ciSpeculativeTrapData* data = new ciSpeculativeTrapData(dp); 1.98 + // data->method() might be null if the MDO is snapshotted 1.99 + // concurrently with a trap 1.100 + if (m != NULL && data->method() == m && dp->bci() == bci) { 1.101 + return data; 1.102 + } 1.103 + break; 1.104 } 1.105 - if (dp->tag() == DataLayout::arg_info_data_tag) { 1.106 - break; // ArgInfoData is at the end of extra data section. 1.107 + default: 1.108 + fatal(err_msg("bad tag = %d", dp->tag())); 1.109 } 1.110 - if (dp->bci() == bci) { 1.111 - assert(dp->tag() == DataLayout::bit_data_tag, "sane"); 1.112 - return new ciBitData(dp); 1.113 + } 1.114 + return NULL; 1.115 +} 1.116 + 1.117 +// Translate a bci to its corresponding data, or NULL. 1.118 +ciProfileData* ciMethodData::bci_to_data(int bci, ciMethod* m) { 1.119 + // If m is not NULL we look for a SpeculativeTrapData entry 1.120 + if (m == NULL) { 1.121 + ciProfileData* data = data_before(bci); 1.122 + for ( ; is_valid(data); data = next_data(data)) { 1.123 + if (data->bci() == bci) { 1.124 + set_hint_di(dp_to_di(data->dp())); 1.125 + return data; 1.126 + } else if (data->bci() > bci) { 1.127 + break; 1.128 + } 1.129 } 1.130 } 1.131 + bool two_free_slots = false; 1.132 + ciProfileData* result = bci_to_extra_data(bci, m, two_free_slots); 1.133 + if (result != NULL) { 1.134 + return result; 1.135 + } 1.136 + if (m != NULL && !two_free_slots) { 1.137 + // We were looking for a SpeculativeTrapData entry we didn't 1.138 + // find. Room is not available for more SpeculativeTrapData 1.139 + // entries, look in the non SpeculativeTrapData entries. 1.140 + return bci_to_data(bci, NULL); 1.141 + } 1.142 return NULL; 1.143 } 1.144 1.145 @@ -525,18 +594,25 @@ 1.146 st->print_cr("--- Extra data:"); 1.147 DataLayout* dp = data_layout_at(data_size()); 1.148 DataLayout* end = data_layout_at(data_size() + extra_data_size()); 1.149 - for (; dp < end; dp = MethodData::next_extra(dp)) { 1.150 - if (dp->tag() == DataLayout::no_tag) continue; 1.151 - if (dp->tag() == DataLayout::bit_data_tag) { 1.152 + for (;; dp = MethodData::next_extra(dp)) { 1.153 + assert(dp < end, "moved past end of extra data"); 1.154 + switch (dp->tag()) { 1.155 + case DataLayout::no_tag: 1.156 + continue; 1.157 + case DataLayout::bit_data_tag: 1.158 data = new BitData(dp); 1.159 - } else { 1.160 - assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo"); 1.161 + break; 1.162 + case DataLayout::arg_info_data_tag: 1.163 data = new ciArgInfoData(dp); 1.164 dp = end; // ArgInfoData is at the end of extra data section. 1.165 + break; 1.166 + default: 1.167 + fatal(err_msg("unexpected tag %d", dp->tag())); 1.168 } 1.169 st->print("%d", dp_to_di(data->dp())); 1.170 st->fill_to(6); 1.171 data->print_data_on(st); 1.172 + if (dp >= end) return; 1.173 } 1.174 } 1.175 1.176 @@ -569,8 +645,8 @@ 1.177 st->cr(); 1.178 } 1.179 1.180 -void ciCallTypeData::print_data_on(outputStream* st) const { 1.181 - print_shared(st, "ciCallTypeData"); 1.182 +void ciCallTypeData::print_data_on(outputStream* st, const char* extra) const { 1.183 + print_shared(st, "ciCallTypeData", extra); 1.184 if (has_arguments()) { 1.185 tab(st, true); 1.186 st->print("argument types"); 1.187 @@ -599,18 +675,18 @@ 1.188 } 1.189 } 1.190 1.191 -void ciReceiverTypeData::print_data_on(outputStream* st) const { 1.192 - print_shared(st, "ciReceiverTypeData"); 1.193 +void ciReceiverTypeData::print_data_on(outputStream* st, const char* extra) const { 1.194 + print_shared(st, "ciReceiverTypeData", extra); 1.195 print_receiver_data_on(st); 1.196 } 1.197 1.198 -void ciVirtualCallData::print_data_on(outputStream* st) const { 1.199 - print_shared(st, "ciVirtualCallData"); 1.200 +void ciVirtualCallData::print_data_on(outputStream* st, const char* extra) const { 1.201 + print_shared(st, "ciVirtualCallData", extra); 1.202 rtd_super()->print_receiver_data_on(st); 1.203 } 1.204 1.205 -void ciVirtualCallTypeData::print_data_on(outputStream* st) const { 1.206 - print_shared(st, "ciVirtualCallTypeData"); 1.207 +void ciVirtualCallTypeData::print_data_on(outputStream* st, const char* extra) const { 1.208 + print_shared(st, "ciVirtualCallTypeData", extra); 1.209 rtd_super()->print_receiver_data_on(st); 1.210 if (has_arguments()) { 1.211 tab(st, true); 1.212 @@ -624,8 +700,15 @@ 1.213 } 1.214 } 1.215 1.216 -void ciParametersTypeData::print_data_on(outputStream* st) const { 1.217 - st->print_cr("Parametertypes"); 1.218 +void ciParametersTypeData::print_data_on(outputStream* st, const char* extra) const { 1.219 + st->print_cr("ciParametersTypeData"); 1.220 parameters()->print_data_on(st); 1.221 } 1.222 + 1.223 +void ciSpeculativeTrapData::print_data_on(outputStream* st, const char* extra) const { 1.224 + st->print_cr("ciSpeculativeTrapData"); 1.225 + tab(st); 1.226 + method()->print_short_name(st); 1.227 + st->cr(); 1.228 +} 1.229 #endif