42
42
ciMethodData::ciMethodData (MethodData* md)
43
43
: ciMetadata(md),
44
44
_data_size(0 ), _extra_data_size(0 ), _data(nullptr ),
45
+ _parameters_data_offset(0 ),
46
+ _exception_handlers_data_offset(0 ),
45
47
// Set an initial hint. Don't use set_hint_di() because
46
48
// first_di() may be out of bounds if data_size is 0.
47
49
_hint_di(first_di()),
@@ -50,8 +52,7 @@ ciMethodData::ciMethodData(MethodData* md)
50
52
// Initialize the escape information (to "don't know.");
51
53
_eflags(0 ), _arg_local(0 ), _arg_stack(0 ), _arg_returned(0 ),
52
54
_invocation_counter(0 ),
53
- _orig(),
54
- _parameters(nullptr ) {}
55
+ _orig() {}
55
56
56
57
// Check for entries that reference an unloaded method
57
58
class PrepareExtraDataClosure : public CleanExtraDataClosure {
@@ -134,8 +135,16 @@ void ciMethodData::load_remaining_extra_data() {
134
135
135
136
// Copy the extra data once it is prepared (i.e. cache populated, no release of extra data lock anymore)
136
137
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);
138
+ (HeapWord*) extra_data_base (),
139
+ // copy everything from extra_data_base() up to parameters_data_base()
140
+ pointer_delta (parameters_data_base (), extra_data_base (), HeapWordSize));
141
+
142
+ // skip parameter data copying. Already done in 'load_data'
143
+
144
+ // copy exception handler data
145
+ Copy::disjoint_words_atomic ((HeapWord*) mdo->exception_handler_data_base (),
146
+ (HeapWord*) exception_handler_data_base (),
147
+ exception_handler_data_size () / HeapWordSize);
139
148
140
149
// speculative trap entries also hold a pointer to a Method so need to be translated
141
150
DataLayout* dp_src = mdo->extra_data_base ();
@@ -195,12 +204,17 @@ bool ciMethodData::load_data() {
195
204
// args_data_limit: ---------------------------
196
205
// | parameter data entries |
197
206
// | ... |
207
+ // param_data_limit: ---------------------------
208
+ // | ex handler data entries |
209
+ // | ... |
198
210
// extra_data_limit: ---------------------------
199
211
//
200
212
// _data_size = extra_data_base - data_base
201
213
// _extra_data_size = extra_data_limit - extra_data_base
202
214
// total_size = _data_size + _extra_data_size
203
- // args_data_limit = data_base + total_size - parameter_data_size
215
+ // args_data_limit = param_data_base
216
+ // param_data_limit = exception_handler_data_base
217
+ // extra_data_limit = extra_data_limit
204
218
205
219
#ifndef ZERO
206
220
// Some Zero platforms do not have expected alignment, and do not use
@@ -218,12 +232,15 @@ bool ciMethodData::load_data() {
218
232
Copy::disjoint_words_atomic ((HeapWord*) mdo->data_base (),
219
233
(HeapWord*) _data,
220
234
_data_size / HeapWordSize);
235
+ // Copy offsets. This is used below
236
+ _parameters_data_offset = mdo->parameters_type_data_di ();
237
+ _exception_handlers_data_offset = mdo->exception_handlers_data_di ();
221
238
222
239
int parameters_data_size = mdo->parameters_size_in_bytes ();
223
240
if (parameters_data_size > 0 ) {
224
241
// Snapshot the parameter data
225
- Copy::disjoint_words_atomic ((HeapWord*) mdo->args_data_limit (),
226
- (HeapWord*) ((address)_data + total_size - parameters_data_size ),
242
+ Copy::disjoint_words_atomic ((HeapWord*) mdo->parameters_data_base (),
243
+ (HeapWord*) parameters_data_base ( ),
227
244
parameters_data_size / HeapWordSize);
228
245
}
229
246
// Traverse the profile data, translating any oops into their
@@ -237,12 +254,12 @@ bool ciMethodData::load_data() {
237
254
data = mdo->next_data (data);
238
255
}
239
256
if (mdo->parameters_type_data () != nullptr ) {
240
- _parameters = data_layout_at (mdo-> parameters_type_data_di () );
241
- ciParametersTypeData* parameters = new ciParametersTypeData (_parameters );
257
+ DataLayout* parameters_data = data_layout_at (_parameters_data_offset );
258
+ ciParametersTypeData* parameters = new ciParametersTypeData (parameters_data );
242
259
parameters->translate_from (mdo->parameters_type_data ());
243
260
}
244
261
245
- assert ((DataLayout*) ((address)_data + total_size - parameters_data_size) == args_data_limit (),
262
+ assert ((DataLayout*) ((address)_data + total_size - parameters_data_size - exception_handler_data_size () ) == args_data_limit (),
246
263
" sanity - parameter data starts after the argument data of the single ArgInfoData entry" );
247
264
load_remaining_extra_data ();
248
265
@@ -367,16 +384,24 @@ ciProfileData* ciMethodData::next_data(ciProfileData* current) {
367
384
return next;
368
385
}
369
386
370
- DataLayout* ciMethodData::next_data_layout (DataLayout* current) {
387
+ DataLayout* ciMethodData::next_data_layout_helper (DataLayout* current, bool extra ) {
371
388
int current_index = dp_to_di ((address)current);
372
389
int next_index = current_index + current->size_in_bytes ();
373
- if (out_of_bounds (next_index)) {
390
+ if (extra ? out_of_bounds_extra (next_index) : out_of_bounds (next_index)) {
374
391
return nullptr ;
375
392
}
376
393
DataLayout* next = data_layout_at (next_index);
377
394
return next;
378
395
}
379
396
397
+ DataLayout* ciMethodData::next_data_layout (DataLayout* current) {
398
+ return next_data_layout_helper (current, false );
399
+ }
400
+
401
+ DataLayout* ciMethodData::next_extra_data_layout (DataLayout* current) {
402
+ return next_data_layout_helper (current, true );
403
+ }
404
+
380
405
ciProfileData* ciMethodData::bci_to_extra_data (int bci, ciMethod* m, bool & two_free_slots) {
381
406
DataLayout* dp = extra_data_base ();
382
407
DataLayout* end = args_data_limit ();
@@ -438,6 +463,19 @@ ciProfileData* ciMethodData::bci_to_data(int bci, ciMethod* m) {
438
463
return nullptr ;
439
464
}
440
465
466
+ ciBitData ciMethodData::exception_handler_bci_to_data (int bci) {
467
+ assert (ProfileExceptionHandlers, " not profiling" );
468
+ assert (_data != nullptr , " must be initialized" );
469
+ for (DataLayout* data = exception_handler_data_base (); data < exception_handler_data_limit (); data = next_extra_data_layout (data)) {
470
+ assert (data != nullptr , " out of bounds?" );
471
+ if (data->bci () == bci) {
472
+ return ciBitData (data);
473
+ }
474
+ }
475
+ // called with invalid bci or wrong Method/MethodData
476
+ ShouldNotReachHere ();
477
+ }
478
+
441
479
// Conservatively decode the trap_state of a ciProfileData.
442
480
int ciMethodData::has_trap_at (ciProfileData* data, int reason) {
443
481
typedef Deoptimization::DeoptReason DR_t;
@@ -612,7 +650,7 @@ uint ciMethodData::arg_modified(int arg) const {
612
650
}
613
651
614
652
ciParametersTypeData* ciMethodData::parameters_type_data () const {
615
- return _parameters != nullptr ? new ciParametersTypeData (_parameters ) : nullptr ;
653
+ return parameter_data_size () != 0 ? new ciParametersTypeData (data_layout_at (_parameters_data_offset) ) : nullptr ;
616
654
}
617
655
618
656
ByteSize ciMethodData::offset_of_slot (ciProfileData* data, ByteSize slot_offset_in_data) {
0 commit comments