36
37 // ------------------------------------------------------------------
38 // ciMethodData::ciMethodData
39 //
40 ciMethodData::ciMethodData(MethodData* md) : ciMetadata(md) {
41 assert(md != NULL, "no null method data");
42 Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
43 _data = NULL;
44 _data_size = 0;
45 _extra_data_size = 0;
46 _current_mileage = 0;
47 _invocation_counter = 0;
48 _backedge_counter = 0;
49 _state = empty_state;
50 _saw_free_extra_data = false;
51 // Set an initial hint. Don't use set_hint_di() because
52 // first_di() may be out of bounds if data_size is 0.
53 _hint_di = first_di();
54 // Initialize the escape information (to "don't know.");
55 _eflags = _arg_local = _arg_stack = _arg_returned = 0;
56 }
57
58 // ------------------------------------------------------------------
59 // ciMethodData::ciMethodData
60 //
61 // No MethodData*.
62 ciMethodData::ciMethodData() : ciMetadata(NULL) {
63 Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
64 _data = NULL;
65 _data_size = 0;
66 _extra_data_size = 0;
67 _current_mileage = 0;
68 _invocation_counter = 0;
69 _backedge_counter = 0;
70 _state = empty_state;
71 _saw_free_extra_data = false;
72 // Set an initial hint. Don't use set_hint_di() because
73 // first_di() may be out of bounds if data_size is 0.
74 _hint_di = first_di();
75 // Initialize the escape information (to "don't know.");
76 _eflags = _arg_local = _arg_stack = _arg_returned = 0;
77 }
78
79 void ciMethodData::load_data() {
80 MethodData* mdo = get_MethodData();
81 if (mdo == NULL) {
82 return;
83 }
84
85 // To do: don't copy the data if it is not "ripe" -- require a minimum #
86 // of invocations.
87
88 // Snapshot the data -- actually, take an approximate snapshot of
89 // the data. Any concurrently executing threads may be changing the
90 // data as we copy it.
91 Copy::disjoint_words((HeapWord*) mdo,
92 (HeapWord*) &_orig,
93 sizeof(_orig) / HeapWordSize);
94 Arena* arena = CURRENT_ENV->arena();
95 _data_size = mdo->data_size();
96 _extra_data_size = mdo->extra_data_size();
97 int total_size = _data_size + _extra_data_size;
98 _data = (intptr_t *) arena->Amalloc(total_size);
99 Copy::disjoint_words((HeapWord*) mdo->data_base(), (HeapWord*) _data, total_size / HeapWordSize);
100
101 // Traverse the profile data, translating any oops into their
102 // ci equivalents.
103 ResourceMark rm;
104 ciProfileData* ci_data = first_data();
105 ProfileData* data = mdo->first_data();
106 while (is_valid(ci_data)) {
107 ci_data->translate_from(data);
108 ci_data = next_data(ci_data);
109 data = mdo->next_data(data);
110 }
111 // Note: Extra data are all BitData, and do not need translation.
112 _current_mileage = MethodData::mileage_of(mdo->method());
113 _invocation_counter = mdo->invocation_count();
114 _backedge_counter = mdo->backedge_count();
115 _state = mdo->is_mature()? mature_state: immature_state;
116
117 _eflags = mdo->eflags();
118 _arg_local = mdo->arg_local();
119 _arg_stack = mdo->arg_stack();
120 _arg_returned = mdo->arg_returned();
121 #ifndef PRODUCT
122 if (ReplayCompiles) {
123 ciReplay::initialize(this);
124 }
125 #endif
126 }
127
128 void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) {
129 for (uint row = 0; row < row_limit(); row++) {
130 Klass* k = data->as_ReceiverTypeData()->receiver(row);
165 case DataLayout::counter_data_tag:
166 return new ciCounterData(data_layout);
167 case DataLayout::jump_data_tag:
168 return new ciJumpData(data_layout);
169 case DataLayout::receiver_type_data_tag:
170 return new ciReceiverTypeData(data_layout);
171 case DataLayout::virtual_call_data_tag:
172 return new ciVirtualCallData(data_layout);
173 case DataLayout::ret_data_tag:
174 return new ciRetData(data_layout);
175 case DataLayout::branch_data_tag:
176 return new ciBranchData(data_layout);
177 case DataLayout::multi_branch_data_tag:
178 return new ciMultiBranchData(data_layout);
179 case DataLayout::arg_info_data_tag:
180 return new ciArgInfoData(data_layout);
181 case DataLayout::call_type_data_tag:
182 return new ciCallTypeData(data_layout);
183 case DataLayout::virtual_call_type_data_tag:
184 return new ciVirtualCallTypeData(data_layout);
185 };
186 }
187
188 // Iteration over data.
189 ciProfileData* ciMethodData::next_data(ciProfileData* current) {
190 int current_index = dp_to_di(current->dp());
191 int next_index = current_index + current->size_in_bytes();
192 ciProfileData* next = data_at(next_index);
193 return next;
194 }
195
196 // Translate a bci to its corresponding data, or NULL.
197 ciProfileData* ciMethodData::bci_to_data(int bci) {
198 ciProfileData* data = data_before(bci);
199 for ( ; is_valid(data); data = next_data(data)) {
200 if (data->bci() == bci) {
201 set_hint_di(dp_to_di(data->dp()));
202 return data;
203 } else if (data->bci() > bci) {
204 break;
301 MethodData* mdo = get_MethodData();
302 if (mdo != NULL) {
303 mdo->set_would_profile(p);
304 }
305 }
306
307 void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) {
308 VM_ENTRY_MARK;
309 MethodData* mdo = get_MethodData();
310 if (mdo != NULL) {
311 ProfileData* data = mdo->bci_to_data(bci);
312 if (data->is_CallTypeData()) {
313 data->as_CallTypeData()->set_argument_type(i, k->get_Klass());
314 } else {
315 assert(data->is_VirtualCallTypeData(), "no arguments!");
316 data->as_VirtualCallTypeData()->set_argument_type(i, k->get_Klass());
317 }
318 }
319 }
320
321 void ciMethodData::set_return_type(int bci, ciKlass* k) {
322 VM_ENTRY_MARK;
323 MethodData* mdo = get_MethodData();
324 if (mdo != NULL) {
325 ProfileData* data = mdo->bci_to_data(bci);
326 if (data->is_CallTypeData()) {
327 data->as_CallTypeData()->set_return_type(k->get_Klass());
328 } else {
329 assert(data->is_VirtualCallTypeData(), "no arguments!");
330 data->as_VirtualCallTypeData()->set_return_type(k->get_Klass());
331 }
332 }
333 }
334
335 bool ciMethodData::has_escape_info() {
336 return eflag_set(MethodData::estimated);
337 }
338
339 void ciMethodData::set_eflag(MethodData::EscapeFlag f) {
340 set_bits(_eflags, f);
587 }
588
589 void ciVirtualCallData::print_data_on(outputStream* st) const {
590 print_shared(st, "ciVirtualCallData");
591 rtd_super()->print_receiver_data_on(st);
592 }
593
594 void ciVirtualCallTypeData::print_data_on(outputStream* st) const {
595 print_shared(st, "ciVirtualCallTypeData");
596 rtd_super()->print_receiver_data_on(st);
597 if (has_arguments()) {
598 tab(st, true);
599 st->print("argument types");
600 args()->print_data_on(st);
601 }
602 if (has_return()) {
603 tab(st, true);
604 st->print("return type");
605 ret()->print_data_on(st);
606 }
607 }
608 #endif
|
36
37 // ------------------------------------------------------------------
38 // ciMethodData::ciMethodData
39 //
40 ciMethodData::ciMethodData(MethodData* md) : ciMetadata(md) {
41 assert(md != NULL, "no null method data");
42 Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
43 _data = NULL;
44 _data_size = 0;
45 _extra_data_size = 0;
46 _current_mileage = 0;
47 _invocation_counter = 0;
48 _backedge_counter = 0;
49 _state = empty_state;
50 _saw_free_extra_data = false;
51 // Set an initial hint. Don't use set_hint_di() because
52 // first_di() may be out of bounds if data_size is 0.
53 _hint_di = first_di();
54 // Initialize the escape information (to "don't know.");
55 _eflags = _arg_local = _arg_stack = _arg_returned = 0;
56 _parameters = NULL;
57 }
58
59 // ------------------------------------------------------------------
60 // ciMethodData::ciMethodData
61 //
62 // No MethodData*.
63 ciMethodData::ciMethodData() : ciMetadata(NULL) {
64 Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
65 _data = NULL;
66 _data_size = 0;
67 _extra_data_size = 0;
68 _current_mileage = 0;
69 _invocation_counter = 0;
70 _backedge_counter = 0;
71 _state = empty_state;
72 _saw_free_extra_data = false;
73 // Set an initial hint. Don't use set_hint_di() because
74 // first_di() may be out of bounds if data_size is 0.
75 _hint_di = first_di();
76 // Initialize the escape information (to "don't know.");
77 _eflags = _arg_local = _arg_stack = _arg_returned = 0;
78 _parameters = NULL;
79 }
80
81 void ciMethodData::load_data() {
82 MethodData* mdo = get_MethodData();
83 if (mdo == NULL) {
84 return;
85 }
86
87 // To do: don't copy the data if it is not "ripe" -- require a minimum #
88 // of invocations.
89
90 // Snapshot the data -- actually, take an approximate snapshot of
91 // the data. Any concurrently executing threads may be changing the
92 // data as we copy it.
93 Copy::disjoint_words((HeapWord*) mdo,
94 (HeapWord*) &_orig,
95 sizeof(_orig) / HeapWordSize);
96 Arena* arena = CURRENT_ENV->arena();
97 _data_size = mdo->data_size();
98 _extra_data_size = mdo->extra_data_size();
99 int total_size = _data_size + _extra_data_size;
100 _data = (intptr_t *) arena->Amalloc(total_size);
101 Copy::disjoint_words((HeapWord*) mdo->data_base(), (HeapWord*) _data, total_size / HeapWordSize);
102
103 // Traverse the profile data, translating any oops into their
104 // ci equivalents.
105 ResourceMark rm;
106 ciProfileData* ci_data = first_data();
107 ProfileData* data = mdo->first_data();
108 while (is_valid(ci_data)) {
109 ci_data->translate_from(data);
110 ci_data = next_data(ci_data);
111 data = mdo->next_data(data);
112 }
113 if (mdo->parameters_type_data() != NULL) {
114 _parameters = data_layout_at(mdo->parameters_type_data_di());
115 ciParametersTypeData* parameters = new ciParametersTypeData(_parameters);
116 parameters->translate_from(mdo->parameters_type_data());
117 }
118
119 // Note: Extra data are all BitData, and do not need translation.
120 _current_mileage = MethodData::mileage_of(mdo->method());
121 _invocation_counter = mdo->invocation_count();
122 _backedge_counter = mdo->backedge_count();
123 _state = mdo->is_mature()? mature_state: immature_state;
124
125 _eflags = mdo->eflags();
126 _arg_local = mdo->arg_local();
127 _arg_stack = mdo->arg_stack();
128 _arg_returned = mdo->arg_returned();
129 #ifndef PRODUCT
130 if (ReplayCompiles) {
131 ciReplay::initialize(this);
132 }
133 #endif
134 }
135
136 void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) {
137 for (uint row = 0; row < row_limit(); row++) {
138 Klass* k = data->as_ReceiverTypeData()->receiver(row);
173 case DataLayout::counter_data_tag:
174 return new ciCounterData(data_layout);
175 case DataLayout::jump_data_tag:
176 return new ciJumpData(data_layout);
177 case DataLayout::receiver_type_data_tag:
178 return new ciReceiverTypeData(data_layout);
179 case DataLayout::virtual_call_data_tag:
180 return new ciVirtualCallData(data_layout);
181 case DataLayout::ret_data_tag:
182 return new ciRetData(data_layout);
183 case DataLayout::branch_data_tag:
184 return new ciBranchData(data_layout);
185 case DataLayout::multi_branch_data_tag:
186 return new ciMultiBranchData(data_layout);
187 case DataLayout::arg_info_data_tag:
188 return new ciArgInfoData(data_layout);
189 case DataLayout::call_type_data_tag:
190 return new ciCallTypeData(data_layout);
191 case DataLayout::virtual_call_type_data_tag:
192 return new ciVirtualCallTypeData(data_layout);
193 case DataLayout::parameters_type_data_tag:
194 return new ciParametersTypeData(data_layout);
195 };
196 }
197
198 // Iteration over data.
199 ciProfileData* ciMethodData::next_data(ciProfileData* current) {
200 int current_index = dp_to_di(current->dp());
201 int next_index = current_index + current->size_in_bytes();
202 ciProfileData* next = data_at(next_index);
203 return next;
204 }
205
206 // Translate a bci to its corresponding data, or NULL.
207 ciProfileData* ciMethodData::bci_to_data(int bci) {
208 ciProfileData* data = data_before(bci);
209 for ( ; is_valid(data); data = next_data(data)) {
210 if (data->bci() == bci) {
211 set_hint_di(dp_to_di(data->dp()));
212 return data;
213 } else if (data->bci() > bci) {
214 break;
311 MethodData* mdo = get_MethodData();
312 if (mdo != NULL) {
313 mdo->set_would_profile(p);
314 }
315 }
316
317 void ciMethodData::set_argument_type(int bci, int i, ciKlass* k) {
318 VM_ENTRY_MARK;
319 MethodData* mdo = get_MethodData();
320 if (mdo != NULL) {
321 ProfileData* data = mdo->bci_to_data(bci);
322 if (data->is_CallTypeData()) {
323 data->as_CallTypeData()->set_argument_type(i, k->get_Klass());
324 } else {
325 assert(data->is_VirtualCallTypeData(), "no arguments!");
326 data->as_VirtualCallTypeData()->set_argument_type(i, k->get_Klass());
327 }
328 }
329 }
330
331 void ciMethodData::set_parameter_type(int i, ciKlass* k) {
332 VM_ENTRY_MARK;
333 MethodData* mdo = get_MethodData();
334 if (mdo != NULL) {
335 mdo->parameters_type_data()->set_type(i, k->get_Klass());
336 }
337 }
338
339 void ciMethodData::set_return_type(int bci, ciKlass* k) {
340 VM_ENTRY_MARK;
341 MethodData* mdo = get_MethodData();
342 if (mdo != NULL) {
343 ProfileData* data = mdo->bci_to_data(bci);
344 if (data->is_CallTypeData()) {
345 data->as_CallTypeData()->set_return_type(k->get_Klass());
346 } else {
347 assert(data->is_VirtualCallTypeData(), "no arguments!");
348 data->as_VirtualCallTypeData()->set_return_type(k->get_Klass());
349 }
350 }
351 }
352
353 bool ciMethodData::has_escape_info() {
354 return eflag_set(MethodData::estimated);
355 }
356
357 void ciMethodData::set_eflag(MethodData::EscapeFlag f) {
358 set_bits(_eflags, f);
605 }
606
607 void ciVirtualCallData::print_data_on(outputStream* st) const {
608 print_shared(st, "ciVirtualCallData");
609 rtd_super()->print_receiver_data_on(st);
610 }
611
612 void ciVirtualCallTypeData::print_data_on(outputStream* st) const {
613 print_shared(st, "ciVirtualCallTypeData");
614 rtd_super()->print_receiver_data_on(st);
615 if (has_arguments()) {
616 tab(st, true);
617 st->print("argument types");
618 args()->print_data_on(st);
619 }
620 if (has_return()) {
621 tab(st, true);
622 st->print("return type");
623 ret()->print_data_on(st);
624 }
625 }
626
627 void ciParametersTypeData::print_data_on(outputStream* st) const {
628 st->print_cr("Parametertypes");
629 parameters()->print_data_on(st);
630 }
631 #endif
|