@@ -120,7 +120,7 @@ void ciMethodData::prepare_metadata() {
120
120
}
121
121
}
122
122
123
- void ciMethodData::load_extra_data () {
123
+ void ciMethodData::load_remaining_extra_data () {
124
124
MethodData* mdo = get_MethodData ();
125
125
MutexLocker ml (mdo->extra_data_lock ());
126
126
// Deferred metadata cleaning due to concurrent class unloading.
@@ -129,6 +129,14 @@ void ciMethodData::load_extra_data() {
129
129
// and no safepoints can introduce more stale metadata.
130
130
NoSafepointVerifier no_safepoint;
131
131
132
+ assert ((mdo->data_size () == _data_size) && (mdo->extra_data_size () == _extra_data_size), " sanity, unchanged" );
133
+ assert (extra_data_base () == (DataLayout*)((address) _data + _data_size), " sanity" );
134
+
135
+ // Copy the extra data once it is prepared (i.e. cache populated, no release of extra data lock anymore)
136
+ Copy::disjoint_words_atomic ((HeapWord*) mdo->extra_data_base (),
137
+ (HeapWord*)((address) _data + _data_size),
138
+ (_extra_data_size - mdo->parameters_size_in_bytes ()) / HeapWordSize);
139
+
132
140
// speculative trap entries also hold a pointer to a Method so need to be translated
133
141
DataLayout* dp_src = mdo->extra_data_base ();
134
142
DataLayout* end_src = mdo->args_data_limit ();
@@ -137,19 +145,7 @@ void ciMethodData::load_extra_data() {
137
145
assert (dp_src < end_src, " moved past end of extra data" );
138
146
assert (((intptr_t )dp_dst) - ((intptr_t )extra_data_base ()) == ((intptr_t )dp_src) - ((intptr_t )mdo->extra_data_base ()), " source and destination don't match" );
139
147
140
- // New traps in the MDO may have been added since we copied the
141
- // data (concurrent deoptimizations before we acquired
142
- // extra_data_lock above) or can be removed (a safepoint may occur
143
- // in the prepare_metadata call above) as we translate the copy:
144
- // update the copy as we go.
145
148
int tag = dp_src->tag ();
146
- size_t entry_size = DataLayout::header_size_in_bytes ();
147
- if (tag != DataLayout::no_tag) {
148
- ProfileData* src_data = dp_src->data_in ();
149
- entry_size = src_data->size_in_bytes ();
150
- }
151
- memcpy (dp_dst, dp_src, entry_size);
152
-
153
149
switch (tag) {
154
150
case DataLayout::speculative_trap_data_tag: {
155
151
ciSpeculativeTrapData data_dst (dp_dst);
@@ -180,9 +176,31 @@ bool ciMethodData::load_data() {
180
176
// To do: don't copy the data if it is not "ripe" -- require a minimum #
181
177
// of invocations.
182
178
183
- // Snapshot the data -- actually, take an approximate snapshot of
184
- // the data. Any concurrently executing threads may be changing the
185
- // data as we copy it.
179
+ // Snapshot the data and extra parameter data first without the extra trap and arg info data.
180
+ // Those are copied in a second step. Actually, an approximate snapshot of the data is taken.
181
+ // Any concurrently executing threads may be changing the data as we copy it.
182
+ //
183
+ // The first snapshot step requires two copies (data entries and parameter data entries) since
184
+ // the MDO is laid out as follows:
185
+ //
186
+ // data_base: ---------------------------
187
+ // | data entries |
188
+ // | ... |
189
+ // extra_data_base: ---------------------------
190
+ // | trap data entries |
191
+ // | ... |
192
+ // | one arg info data entry |
193
+ // | data for each arg |
194
+ // | ... |
195
+ // args_data_limit: ---------------------------
196
+ // | parameter data entries |
197
+ // | ... |
198
+ // extra_data_limit: ---------------------------
199
+ //
200
+ // _data_size = extra_data_base - data_base
201
+ // _extra_data_size = extra_data_limit - extra_data_base
202
+ // total_size = _data_size + _extra_data_size
203
+ // args_data_limit = data_base + total_size - parameter_data_size
186
204
STATIC_ASSERT (sizeof (_orig) % HeapWordSize == 0 ); // "align"
187
205
Copy::disjoint_words_atomic ((HeapWord*) &mdo->_compiler_counters ,
188
206
(HeapWord*) &_orig,
@@ -194,8 +212,15 @@ bool ciMethodData::load_data() {
194
212
_data = (intptr_t *) arena->Amalloc (total_size);
195
213
Copy::disjoint_words_atomic ((HeapWord*) mdo->data_base (),
196
214
(HeapWord*) _data,
197
- total_size / HeapWordSize);
215
+ _data_size / HeapWordSize);
198
216
217
+ int parameters_data_size = mdo->parameters_size_in_bytes ();
218
+ if (parameters_data_size > 0 ) {
219
+ // Snapshot the parameter data
220
+ Copy::disjoint_words_atomic ((HeapWord*) mdo->args_data_limit (),
221
+ (HeapWord*) ((address)_data + total_size - parameters_data_size),
222
+ parameters_data_size / HeapWordSize);
223
+ }
199
224
// Traverse the profile data, translating any oops into their
200
225
// ci equivalents.
201
226
ResourceMark rm;
@@ -212,7 +237,9 @@ bool ciMethodData::load_data() {
212
237
parameters->translate_from (mdo->parameters_type_data ());
213
238
}
214
239
215
- load_extra_data ();
240
+ assert ((DataLayout*) ((address)_data + total_size - parameters_data_size) == args_data_limit (),
241
+ " sanity - parameter data starts after the argument data of the single ArgInfoData entry" );
242
+ load_remaining_extra_data ();
216
243
217
244
// Note: Extra data are all BitData, and do not need translation.
218
245
_current_mileage = MethodData::mileage_of (mdo->method ());
@@ -324,7 +351,7 @@ ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_f
324
351
two_free_slots = (MethodData::next_extra (dp)->tag () == DataLayout::no_tag);
325
352
return NULL ;
326
353
case DataLayout::arg_info_data_tag:
327
- return NULL ; // ArgInfoData is at the end of extra data section .
354
+ return NULL ; // ArgInfoData is after the trap data right before the parameter data .
328
355
case DataLayout::bit_data_tag:
329
356
if (m == NULL && dp->bci () == bci) {
330
357
return new ciBitData (dp);
@@ -735,7 +762,7 @@ void ciMethodData::print_data_on(outputStream* st) {
735
762
break ;
736
763
case DataLayout::arg_info_data_tag:
737
764
data = new ciArgInfoData (dp);
738
- dp = end; // ArgInfoData is at the end of extra data section .
765
+ dp = end; // ArgInfoData is after the trap data right before the parameter data .
739
766
break ;
740
767
case DataLayout::speculative_trap_data_tag:
741
768
data = new ciSpeculativeTrapData (dp);
0 commit comments