comparison src/share/vm/ci/ciReplay.cpp @ 18041:52b4284cb496

Merge with jdk8u20-b26
author Gilles Duboscq <duboscq@ssw.jku.at>
date Wed, 15 Oct 2014 16:02:50 +0200
parents 4ca6dc0799b6 653e11c86c5a
children
comparison
equal deleted inserted replaced
17606:45d7b2c7029d 18041:52b4284cb496
22 */ 22 */
23 23
24 #include "precompiled.hpp" 24 #include "precompiled.hpp"
25 #include "ci/ciMethodData.hpp" 25 #include "ci/ciMethodData.hpp"
26 #include "ci/ciReplay.hpp" 26 #include "ci/ciReplay.hpp"
27 #include "ci/ciSymbol.hpp"
28 #include "ci/ciKlass.hpp"
27 #include "ci/ciUtilities.hpp" 29 #include "ci/ciUtilities.hpp"
28 #include "compiler/compileBroker.hpp" 30 #include "compiler/compileBroker.hpp"
29 #include "memory/allocation.inline.hpp" 31 #include "memory/allocation.inline.hpp"
30 #include "memory/oopFactory.hpp" 32 #include "memory/oopFactory.hpp"
31 #include "memory/resourceArea.hpp" 33 #include "memory/resourceArea.hpp"
35 #ifndef PRODUCT 37 #ifndef PRODUCT
36 38
37 // ciReplay 39 // ciReplay
38 40
39 typedef struct _ciMethodDataRecord { 41 typedef struct _ciMethodDataRecord {
40 const char* klass; 42 const char* _klass_name;
41 const char* method; 43 const char* _method_name;
42 const char* signature; 44 const char* _signature;
43 int state; 45
44 int current_mileage; 46 int _state;
45 intptr_t* data; 47 int _current_mileage;
46 int data_length; 48
47 char* orig_data; 49 intptr_t* _data;
48 int orig_data_length; 50 char* _orig_data;
49 int oops_length; 51 jobject* _oops_handles;
50 jobject* oops_handles; 52 int* _oops_offsets;
51 int* oops_offsets; 53 int _data_length;
54 int _orig_data_length;
55 int _oops_length;
52 } ciMethodDataRecord; 56 } ciMethodDataRecord;
53 57
54 typedef struct _ciMethodRecord { 58 typedef struct _ciMethodRecord {
55 const char* klass; 59 const char* _klass_name;
56 const char* method; 60 const char* _method_name;
57 const char* signature; 61 const char* _signature;
58 int instructions_size; 62
59 int interpreter_invocation_count; 63 int _instructions_size;
60 int interpreter_throwout_count; 64 int _interpreter_invocation_count;
61 int invocation_counter; 65 int _interpreter_throwout_count;
62 int backedge_counter; 66 int _invocation_counter;
67 int _backedge_counter;
63 } ciMethodRecord; 68 } ciMethodRecord;
64 69
65 class CompileReplay; 70 typedef struct _ciInlineRecord {
71 const char* _klass_name;
72 const char* _method_name;
73 const char* _signature;
74
75 int _inline_depth;
76 int _inline_bci;
77 } ciInlineRecord;
78
79 class CompileReplay;
66 static CompileReplay* replay_state; 80 static CompileReplay* replay_state;
67 81
68 class CompileReplay : public StackObj { 82 class CompileReplay : public StackObj {
69 private: 83 private:
70 FILE* stream; 84 FILE* _stream;
71 Thread* thread; 85 Thread* _thread;
72 Handle protection_domain; 86 Handle _protection_domain;
73 Handle loader; 87 Handle _loader;
74 88
75 GrowableArray<ciMethodRecord*> ci_method_records; 89 GrowableArray<ciMethodRecord*> _ci_method_records;
76 GrowableArray<ciMethodDataRecord*> ci_method_data_records; 90 GrowableArray<ciMethodDataRecord*> _ci_method_data_records;
91
92 // Use pointer because we may need to return inline records
93 // without destroying them.
94 GrowableArray<ciInlineRecord*>* _ci_inline_records;
77 95
78 const char* _error_message; 96 const char* _error_message;
79 97
80 char* bufptr; 98 char* _bufptr;
81 char* buffer; 99 char* _buffer;
82 int buffer_length; 100 int _buffer_length;
83 int buffer_end; 101 int _buffer_pos;
84 int line_no; 102
103 // "compile" data
104 ciKlass* _iklass;
105 Method* _imethod;
106 int _entry_bci;
107 int _comp_level;
85 108
86 public: 109 public:
87 CompileReplay(const char* filename, TRAPS) { 110 CompileReplay(const char* filename, TRAPS) {
88 thread = THREAD; 111 _thread = THREAD;
89 loader = Handle(thread, SystemDictionary::java_system_loader()); 112 _loader = Handle(_thread, SystemDictionary::java_system_loader());
90 stream = fopen(filename, "rt"); 113 _protection_domain = Handle();
91 if (stream == NULL) { 114
115 _stream = fopen(filename, "rt");
116 if (_stream == NULL) {
92 fprintf(stderr, "ERROR: Can't open replay file %s\n", filename); 117 fprintf(stderr, "ERROR: Can't open replay file %s\n", filename);
93 } 118 }
94 buffer_length = 32; 119
95 buffer = NEW_RESOURCE_ARRAY(char, buffer_length); 120 _ci_inline_records = NULL;
96 _error_message = NULL; 121 _error_message = NULL;
97 122
123 _buffer_length = 32;
124 _buffer = NEW_RESOURCE_ARRAY(char, _buffer_length);
125 _bufptr = _buffer;
126 _buffer_pos = 0;
127
128 _imethod = NULL;
129 _iklass = NULL;
130 _entry_bci = 0;
131 _comp_level = 0;
132
98 test(); 133 test();
99 } 134 }
100 135
101 ~CompileReplay() { 136 ~CompileReplay() {
102 if (stream != NULL) fclose(stream); 137 if (_stream != NULL) fclose(_stream);
103 } 138 }
104 139
105 void test() { 140 void test() {
106 strcpy(buffer, "1 2 foo 4 bar 0x9 \"this is it\""); 141 strcpy(_buffer, "1 2 foo 4 bar 0x9 \"this is it\"");
107 bufptr = buffer; 142 _bufptr = _buffer;
108 assert(parse_int("test") == 1, "what"); 143 assert(parse_int("test") == 1, "what");
109 assert(parse_int("test") == 2, "what"); 144 assert(parse_int("test") == 2, "what");
110 assert(strcmp(parse_string(), "foo") == 0, "what"); 145 assert(strcmp(parse_string(), "foo") == 0, "what");
111 assert(parse_int("test") == 4, "what"); 146 assert(parse_int("test") == 4, "what");
112 assert(strcmp(parse_string(), "bar") == 0, "what"); 147 assert(strcmp(parse_string(), "bar") == 0, "what");
113 assert(parse_intptr_t("test") == 9, "what"); 148 assert(parse_intptr_t("test") == 9, "what");
114 assert(strcmp(parse_quoted_string(), "this is it") == 0, "what"); 149 assert(strcmp(parse_quoted_string(), "this is it") == 0, "what");
115 } 150 }
116 151
117 bool had_error() { 152 bool had_error() {
118 return _error_message != NULL || thread->has_pending_exception(); 153 return _error_message != NULL || _thread->has_pending_exception();
119 } 154 }
120 155
121 bool can_replay() { 156 bool can_replay() {
122 return !(stream == NULL || had_error()); 157 return !(_stream == NULL || had_error());
123 } 158 }
124 159
125 void report_error(const char* msg) { 160 void report_error(const char* msg) {
126 _error_message = msg; 161 _error_message = msg;
127 // Restore the buffer contents for error reporting 162 // Restore the _buffer contents for error reporting
128 for (int i = 0; i < buffer_end; i++) { 163 for (int i = 0; i < _buffer_pos; i++) {
129 if (buffer[i] == '\0') buffer[i] = ' '; 164 if (_buffer[i] == '\0') _buffer[i] = ' ';
130 } 165 }
131 } 166 }
132 167
133 int parse_int(const char* label) { 168 int parse_int(const char* label) {
134 if (had_error()) { 169 if (had_error()) {
135 return 0; 170 return 0;
136 } 171 }
137 172
138 int v = 0; 173 int v = 0;
139 int read; 174 int read;
140 if (sscanf(bufptr, "%i%n", &v, &read) != 1) { 175 if (sscanf(_bufptr, "%i%n", &v, &read) != 1) {
141 report_error(label); 176 report_error(label);
142 } else { 177 } else {
143 bufptr += read; 178 _bufptr += read;
144 } 179 }
145 return v; 180 return v;
146 } 181 }
147 182
148 intptr_t parse_intptr_t(const char* label) { 183 intptr_t parse_intptr_t(const char* label) {
150 return 0; 185 return 0;
151 } 186 }
152 187
153 intptr_t v = 0; 188 intptr_t v = 0;
154 int read; 189 int read;
155 if (sscanf(bufptr, INTPTR_FORMAT "%n", &v, &read) != 1) { 190 if (sscanf(_bufptr, INTPTR_FORMAT "%n", &v, &read) != 1) {
156 report_error(label); 191 report_error(label);
157 } else { 192 } else {
158 bufptr += read; 193 _bufptr += read;
159 } 194 }
160 return v; 195 return v;
161 } 196 }
162 197
163 void skip_ws() { 198 void skip_ws() {
164 // Skip any leading whitespace 199 // Skip any leading whitespace
165 while (*bufptr == ' ' || *bufptr == '\t') { 200 while (*_bufptr == ' ' || *_bufptr == '\t') {
166 bufptr++; 201 _bufptr++;
167 } 202 }
168 } 203 }
169 204
170 205
171 char* scan_and_terminate(char delim) { 206 char* scan_and_terminate(char delim) {
172 char* str = bufptr; 207 char* str = _bufptr;
173 while (*bufptr != delim && *bufptr != '\0') { 208 while (*_bufptr != delim && *_bufptr != '\0') {
174 bufptr++; 209 _bufptr++;
175 } 210 }
176 if (*bufptr != '\0') { 211 if (*_bufptr != '\0') {
177 *bufptr++ = '\0'; 212 *_bufptr++ = '\0';
178 } 213 }
179 if (bufptr == str) { 214 if (_bufptr == str) {
180 // nothing here 215 // nothing here
181 return NULL; 216 return NULL;
182 } 217 }
183 return str; 218 return str;
184 } 219 }
193 char* parse_quoted_string() { 228 char* parse_quoted_string() {
194 if (had_error()) return NULL; 229 if (had_error()) return NULL;
195 230
196 skip_ws(); 231 skip_ws();
197 232
198 if (*bufptr == '"') { 233 if (*_bufptr == '"') {
199 bufptr++; 234 _bufptr++;
200 return scan_and_terminate('"'); 235 return scan_and_terminate('"');
201 } else { 236 } else {
202 return scan_and_terminate(' '); 237 return scan_and_terminate(' ');
203 } 238 }
204 } 239 }
271 // Parse a valid klass name and look it up 306 // Parse a valid klass name and look it up
272 Klass* parse_klass(TRAPS) { 307 Klass* parse_klass(TRAPS) {
273 const char* str = parse_escaped_string(); 308 const char* str = parse_escaped_string();
274 Symbol* klass_name = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL); 309 Symbol* klass_name = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL);
275 if (klass_name != NULL) { 310 if (klass_name != NULL) {
276 Klass* k = SystemDictionary::resolve_or_fail(klass_name, loader, protection_domain, true, THREAD); 311 Klass* k = NULL;
312 if (_iklass != NULL) {
313 k = (Klass*)_iklass->find_klass(ciSymbol::make(klass_name->as_C_string()))->constant_encoding();
314 } else {
315 k = SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, THREAD);
316 }
277 if (HAS_PENDING_EXCEPTION) { 317 if (HAS_PENDING_EXCEPTION) {
278 oop throwable = PENDING_EXCEPTION; 318 oop throwable = PENDING_EXCEPTION;
279 java_lang_Throwable::print(throwable, tty); 319 java_lang_Throwable::print(throwable, tty);
280 tty->cr(); 320 tty->cr();
281 report_error(str); 321 report_error(str);
287 } 327 }
288 328
289 // Lookup a klass 329 // Lookup a klass
290 Klass* resolve_klass(const char* klass, TRAPS) { 330 Klass* resolve_klass(const char* klass, TRAPS) {
291 Symbol* klass_name = SymbolTable::lookup(klass, (int)strlen(klass), CHECK_NULL); 331 Symbol* klass_name = SymbolTable::lookup(klass, (int)strlen(klass), CHECK_NULL);
292 return SystemDictionary::resolve_or_fail(klass_name, loader, protection_domain, true, CHECK_NULL); 332 return SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, CHECK_NULL);
293 } 333 }
294 334
295 // Parse the standard tuple of <klass> <name> <signature> 335 // Parse the standard tuple of <klass> <name> <signature>
296 Method* parse_method(TRAPS) { 336 Method* parse_method(TRAPS) {
297 InstanceKlass* k = (InstanceKlass*)parse_klass(CHECK_NULL); 337 InstanceKlass* k = (InstanceKlass*)parse_klass(CHECK_NULL);
302 report_error("Can't find method"); 342 report_error("Can't find method");
303 } 343 }
304 return m; 344 return m;
305 } 345 }
306 346
347 int get_line(int c) {
348 while(c != EOF) {
349 if (_buffer_pos + 1 >= _buffer_length) {
350 int new_length = _buffer_length * 2;
351 // Next call will throw error in case of OOM.
352 _buffer = REALLOC_RESOURCE_ARRAY(char, _buffer, _buffer_length, new_length);
353 _buffer_length = new_length;
354 }
355 if (c == '\n') {
356 c = getc(_stream); // get next char
357 break;
358 } else if (c == '\r') {
359 // skip LF
360 } else {
361 _buffer[_buffer_pos++] = c;
362 }
363 c = getc(_stream);
364 }
365 // null terminate it, reset the pointer
366 _buffer[_buffer_pos] = '\0'; // NL or EOF
367 _buffer_pos = 0;
368 _bufptr = _buffer;
369 return c;
370 }
371
307 // Process each line of the replay file executing each command until 372 // Process each line of the replay file executing each command until
308 // the file ends. 373 // the file ends.
309 void process(TRAPS) { 374 void process(TRAPS) {
310 line_no = 1; 375 int line_no = 1;
311 int pos = 0; 376 int c = getc(_stream);
312 int c = getc(stream);
313 while(c != EOF) { 377 while(c != EOF) {
314 if (pos + 1 >= buffer_length) { 378 c = get_line(c);
315 int newl = buffer_length * 2; 379 process_command(THREAD);
316 char* newb = NEW_RESOURCE_ARRAY(char, newl); 380 if (had_error()) {
317 memcpy(newb, buffer, pos); 381 tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
318 buffer = newb; 382 if (ReplayIgnoreInitErrors) {
319 buffer_length = newl; 383 CLEAR_PENDING_EXCEPTION;
320 } 384 _error_message = NULL;
321 if (c == '\n') { 385 } else {
322 // null terminate it, reset the pointer and process the line
323 buffer[pos] = '\0';
324 buffer_end = pos++;
325 bufptr = buffer;
326 process_command(CHECK);
327 if (had_error()) {
328 tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
329 tty->print_cr("%s", buffer);
330 return; 386 return;
331 } 387 }
332 pos = 0; 388 }
333 buffer_end = 0; 389 line_no++;
334 line_no++;
335 } else if (c == '\r') {
336 // skip LF
337 } else {
338 buffer[pos++] = c;
339 }
340 c = getc(stream);
341 } 390 }
342 } 391 }
343 392
344 void process_command(TRAPS) { 393 void process_command(TRAPS) {
345 char* cmd = parse_string(); 394 char* cmd = parse_string();
394 return false; 443 return false;
395 } 444 }
396 return true; 445 return true;
397 } 446 }
398 447
399 // compile <klass> <name> <signature> <entry_bci> <comp_level> 448 // compile <klass> <name> <signature> <entry_bci> <comp_level> inline <count> <depth> <bci> <klass> <name> <signature> ...
449 void* process_inline(ciMethod* imethod, Method* m, int entry_bci, int comp_level, TRAPS) {
450 _imethod = m;
451 _iklass = imethod->holder();
452 _entry_bci = entry_bci;
453 _comp_level = comp_level;
454 int line_no = 1;
455 int c = getc(_stream);
456 while(c != EOF) {
457 c = get_line(c);
458 // Expecting only lines with "compile" command in inline replay file.
459 char* cmd = parse_string();
460 if (cmd == NULL || strcmp("compile", cmd) != 0) {
461 return NULL;
462 }
463 process_compile(CHECK_NULL);
464 if (had_error()) {
465 tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
466 tty->print_cr("%s", _buffer);
467 return NULL;
468 }
469 if (_ci_inline_records != NULL && _ci_inline_records->length() > 0) {
470 // Found inlining record for the requested method.
471 return _ci_inline_records;
472 }
473 line_no++;
474 }
475 return NULL;
476 }
477
478 // compile <klass> <name> <signature> <entry_bci> <comp_level> inline <count> <depth> <bci> <klass> <name> <signature> ...
400 void process_compile(TRAPS) { 479 void process_compile(TRAPS) {
401 Method* method = parse_method(CHECK); 480 Method* method = parse_method(CHECK);
402 if (had_error()) return; 481 if (had_error()) return;
403 int entry_bci = parse_int("entry_bci"); 482 int entry_bci = parse_int("entry_bci");
404 const char* comp_level_label = "comp_level"; 483 const char* comp_level_label = "comp_level";
407 if (had_error() && (error_message() == comp_level_label)) { 486 if (had_error() && (error_message() == comp_level_label)) {
408 comp_level = CompLevel_full_optimization; 487 comp_level = CompLevel_full_optimization;
409 } 488 }
410 if (!is_valid_comp_level(comp_level)) { 489 if (!is_valid_comp_level(comp_level)) {
411 return; 490 return;
491 }
492 if (_imethod != NULL) {
493 // Replay Inlining
494 if (entry_bci != _entry_bci || comp_level != _comp_level) {
495 return;
496 }
497 const char* iklass_name = _imethod->method_holder()->name()->as_utf8();
498 const char* imethod_name = _imethod->name()->as_utf8();
499 const char* isignature = _imethod->signature()->as_utf8();
500 const char* klass_name = method->method_holder()->name()->as_utf8();
501 const char* method_name = method->name()->as_utf8();
502 const char* signature = method->signature()->as_utf8();
503 if (strcmp(iklass_name, klass_name) != 0 ||
504 strcmp(imethod_name, method_name) != 0 ||
505 strcmp(isignature, signature) != 0) {
506 return;
507 }
508 }
509 int inline_count = 0;
510 if (parse_tag_and_count("inline", inline_count)) {
511 // Record inlining data
512 _ci_inline_records = new GrowableArray<ciInlineRecord*>();
513 for (int i = 0; i < inline_count; i++) {
514 int depth = parse_int("inline_depth");
515 int bci = parse_int("inline_bci");
516 if (had_error()) {
517 break;
518 }
519 Method* inl_method = parse_method(CHECK);
520 if (had_error()) {
521 break;
522 }
523 new_ciInlineRecord(inl_method, bci, depth);
524 }
525 }
526 if (_imethod != NULL) {
527 return; // Replay Inlining
412 } 528 }
413 Klass* k = method->method_holder(); 529 Klass* k = method->method_holder();
414 ((InstanceKlass*)k)->initialize(THREAD); 530 ((InstanceKlass*)k)->initialize(THREAD);
415 if (HAS_PENDING_EXCEPTION) { 531 if (HAS_PENDING_EXCEPTION) {
416 oop throwable = PENDING_EXCEPTION; 532 oop throwable = PENDING_EXCEPTION;
440 // 556 //
441 void process_ciMethod(TRAPS) { 557 void process_ciMethod(TRAPS) {
442 Method* method = parse_method(CHECK); 558 Method* method = parse_method(CHECK);
443 if (had_error()) return; 559 if (had_error()) return;
444 ciMethodRecord* rec = new_ciMethod(method); 560 ciMethodRecord* rec = new_ciMethod(method);
445 rec->invocation_counter = parse_int("invocation_counter"); 561 rec->_invocation_counter = parse_int("invocation_counter");
446 rec->backedge_counter = parse_int("backedge_counter"); 562 rec->_backedge_counter = parse_int("backedge_counter");
447 rec->interpreter_invocation_count = parse_int("interpreter_invocation_count"); 563 rec->_interpreter_invocation_count = parse_int("interpreter_invocation_count");
448 rec->interpreter_throwout_count = parse_int("interpreter_throwout_count"); 564 rec->_interpreter_throwout_count = parse_int("interpreter_throwout_count");
449 rec->instructions_size = parse_int("instructions_size"); 565 rec->_instructions_size = parse_int("instructions_size");
450 } 566 }
451 567
452 // ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length> 568 // ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length>
453 void process_ciMethodData(TRAPS) { 569 void process_ciMethodData(TRAPS) {
454 Method* method = parse_method(CHECK); 570 Method* method = parse_method(CHECK);
455 if (had_error()) return; 571 if (had_error()) return;
456 /* jsut copied from Method, to build interpret data*/ 572 /* just copied from Method, to build interpret data*/
457 if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) { 573 if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
458 return; 574 return;
459 } 575 }
576 // To be properly initialized, some profiling in the MDO needs the
577 // method to be rewritten (number of arguments at a call for
578 // instance)
579 method->method_holder()->link_class(CHECK);
460 // methodOopDesc::build_interpreter_method_data(method, CHECK); 580 // methodOopDesc::build_interpreter_method_data(method, CHECK);
461 { 581 {
462 // Grab a lock here to prevent multiple 582 // Grab a lock here to prevent multiple
463 // MethodData*s from being created. 583 // MethodData*s from being created.
464 MutexLocker ml(MethodData_lock, THREAD); 584 MutexLocker ml(MethodData_lock, THREAD);
469 } 589 }
470 } 590 }
471 591
472 // collect and record all the needed information for later 592 // collect and record all the needed information for later
473 ciMethodDataRecord* rec = new_ciMethodData(method); 593 ciMethodDataRecord* rec = new_ciMethodData(method);
474 rec->state = parse_int("state"); 594 rec->_state = parse_int("state");
475 rec->current_mileage = parse_int("current_mileage"); 595 rec->_current_mileage = parse_int("current_mileage");
476 596
477 rec->orig_data = parse_data("orig", rec->orig_data_length); 597 rec->_orig_data = parse_data("orig", rec->_orig_data_length);
478 if (rec->orig_data == NULL) { 598 if (rec->_orig_data == NULL) {
479 return; 599 return;
480 } 600 }
481 rec->data = parse_intptr_data("data", rec->data_length); 601 rec->_data = parse_intptr_data("data", rec->_data_length);
482 if (rec->data == NULL) { 602 if (rec->_data == NULL) {
483 return; 603 return;
484 } 604 }
485 if (!parse_tag_and_count("oops", rec->oops_length)) { 605 if (!parse_tag_and_count("oops", rec->_oops_length)) {
486 return; 606 return;
487 } 607 }
488 rec->oops_handles = NEW_RESOURCE_ARRAY(jobject, rec->oops_length); 608 rec->_oops_handles = NEW_RESOURCE_ARRAY(jobject, rec->_oops_length);
489 rec->oops_offsets = NEW_RESOURCE_ARRAY(int, rec->oops_length); 609 rec->_oops_offsets = NEW_RESOURCE_ARRAY(int, rec->_oops_length);
490 for (int i = 0; i < rec->oops_length; i++) { 610 for (int i = 0; i < rec->_oops_length; i++) {
491 int offset = parse_int("offset"); 611 int offset = parse_int("offset");
492 if (had_error()) { 612 if (had_error()) {
493 return; 613 return;
494 } 614 }
495 Klass* k = parse_klass(CHECK); 615 Klass* k = parse_klass(CHECK);
496 rec->oops_offsets[i] = offset; 616 rec->_oops_offsets[i] = offset;
497 KlassHandle *kh = NEW_C_HEAP_OBJ(KlassHandle, mtCompiler); 617 KlassHandle *kh = NEW_C_HEAP_OBJ(KlassHandle, mtCompiler);
498 ::new ((void*)kh) KlassHandle(THREAD, k); 618 ::new ((void*)kh) KlassHandle(THREAD, k);
499 rec->oops_handles[i] = (jobject)kh; 619 rec->_oops_handles[i] = (jobject)kh;
500 } 620 }
501 } 621 }
502 622
503 // instanceKlass <name> 623 // instanceKlass <name>
504 // 624 //
568 case JVM_CONSTANT_InterfaceMethodref: 688 case JVM_CONSTANT_InterfaceMethodref:
569 case JVM_CONSTANT_NameAndType: 689 case JVM_CONSTANT_NameAndType:
570 case JVM_CONSTANT_Utf8: 690 case JVM_CONSTANT_Utf8:
571 case JVM_CONSTANT_Integer: 691 case JVM_CONSTANT_Integer:
572 case JVM_CONSTANT_Float: 692 case JVM_CONSTANT_Float:
693 case JVM_CONSTANT_MethodHandle:
694 case JVM_CONSTANT_MethodType:
695 case JVM_CONSTANT_InvokeDynamic:
573 if (tag != cp->tag_at(i).value()) { 696 if (tag != cp->tag_at(i).value()) {
574 report_error("tag mismatch: wrong class files?"); 697 report_error("tag mismatch: wrong class files?");
575 return; 698 return;
576 } 699 }
577 break; 700 break;
727 #endif // INCLUDE_JVMTI 850 #endif // INCLUDE_JVMTI
728 851
729 // Create and initialize a record for a ciMethod 852 // Create and initialize a record for a ciMethod
730 ciMethodRecord* new_ciMethod(Method* method) { 853 ciMethodRecord* new_ciMethod(Method* method) {
731 ciMethodRecord* rec = NEW_RESOURCE_OBJ(ciMethodRecord); 854 ciMethodRecord* rec = NEW_RESOURCE_OBJ(ciMethodRecord);
732 rec->klass = method->method_holder()->name()->as_utf8(); 855 rec->_klass_name = method->method_holder()->name()->as_utf8();
733 rec->method = method->name()->as_utf8(); 856 rec->_method_name = method->name()->as_utf8();
734 rec->signature = method->signature()->as_utf8(); 857 rec->_signature = method->signature()->as_utf8();
735 ci_method_records.append(rec); 858 _ci_method_records.append(rec);
736 return rec; 859 return rec;
737 } 860 }
738 861
739 // Lookup data for a ciMethod 862 // Lookup data for a ciMethod
740 ciMethodRecord* find_ciMethodRecord(Method* method) { 863 ciMethodRecord* find_ciMethodRecord(Method* method) {
741 const char* klass_name = method->method_holder()->name()->as_utf8(); 864 const char* klass_name = method->method_holder()->name()->as_utf8();
742 const char* method_name = method->name()->as_utf8(); 865 const char* method_name = method->name()->as_utf8();
743 const char* signature = method->signature()->as_utf8(); 866 const char* signature = method->signature()->as_utf8();
744 for (int i = 0; i < ci_method_records.length(); i++) { 867 for (int i = 0; i < _ci_method_records.length(); i++) {
745 ciMethodRecord* rec = ci_method_records.at(i); 868 ciMethodRecord* rec = _ci_method_records.at(i);
746 if (strcmp(rec->klass, klass_name) == 0 && 869 if (strcmp(rec->_klass_name, klass_name) == 0 &&
747 strcmp(rec->method, method_name) == 0 && 870 strcmp(rec->_method_name, method_name) == 0 &&
748 strcmp(rec->signature, signature) == 0) { 871 strcmp(rec->_signature, signature) == 0) {
749 return rec; 872 return rec;
750 } 873 }
751 } 874 }
752 return NULL; 875 return NULL;
753 } 876 }
754 877
755 // Create and initialize a record for a ciMethodData 878 // Create and initialize a record for a ciMethodData
756 ciMethodDataRecord* new_ciMethodData(Method* method) { 879 ciMethodDataRecord* new_ciMethodData(Method* method) {
757 ciMethodDataRecord* rec = NEW_RESOURCE_OBJ(ciMethodDataRecord); 880 ciMethodDataRecord* rec = NEW_RESOURCE_OBJ(ciMethodDataRecord);
758 rec->klass = method->method_holder()->name()->as_utf8(); 881 rec->_klass_name = method->method_holder()->name()->as_utf8();
759 rec->method = method->name()->as_utf8(); 882 rec->_method_name = method->name()->as_utf8();
760 rec->signature = method->signature()->as_utf8(); 883 rec->_signature = method->signature()->as_utf8();
761 ci_method_data_records.append(rec); 884 _ci_method_data_records.append(rec);
762 return rec; 885 return rec;
763 } 886 }
764 887
765 // Lookup data for a ciMethodData 888 // Lookup data for a ciMethodData
766 ciMethodDataRecord* find_ciMethodDataRecord(Method* method) { 889 ciMethodDataRecord* find_ciMethodDataRecord(Method* method) {
767 const char* klass_name = method->method_holder()->name()->as_utf8(); 890 const char* klass_name = method->method_holder()->name()->as_utf8();
768 const char* method_name = method->name()->as_utf8(); 891 const char* method_name = method->name()->as_utf8();
769 const char* signature = method->signature()->as_utf8(); 892 const char* signature = method->signature()->as_utf8();
770 for (int i = 0; i < ci_method_data_records.length(); i++) { 893 for (int i = 0; i < _ci_method_data_records.length(); i++) {
771 ciMethodDataRecord* rec = ci_method_data_records.at(i); 894 ciMethodDataRecord* rec = _ci_method_data_records.at(i);
772 if (strcmp(rec->klass, klass_name) == 0 && 895 if (strcmp(rec->_klass_name, klass_name) == 0 &&
773 strcmp(rec->method, method_name) == 0 && 896 strcmp(rec->_method_name, method_name) == 0 &&
774 strcmp(rec->signature, signature) == 0) { 897 strcmp(rec->_signature, signature) == 0) {
775 return rec; 898 return rec;
899 }
900 }
901 return NULL;
902 }
903
904 // Create and initialize a record for a ciInlineRecord
905 ciInlineRecord* new_ciInlineRecord(Method* method, int bci, int depth) {
906 ciInlineRecord* rec = NEW_RESOURCE_OBJ(ciInlineRecord);
907 rec->_klass_name = method->method_holder()->name()->as_utf8();
908 rec->_method_name = method->name()->as_utf8();
909 rec->_signature = method->signature()->as_utf8();
910 rec->_inline_bci = bci;
911 rec->_inline_depth = depth;
912 _ci_inline_records->append(rec);
913 return rec;
914 }
915
916 // Lookup inlining data for a ciMethod
917 ciInlineRecord* find_ciInlineRecord(Method* method, int bci, int depth) {
918 if (_ci_inline_records != NULL) {
919 return find_ciInlineRecord(_ci_inline_records, method, bci, depth);
920 }
921 return NULL;
922 }
923
924 static ciInlineRecord* find_ciInlineRecord(GrowableArray<ciInlineRecord*>* records,
925 Method* method, int bci, int depth) {
926 if (records != NULL) {
927 const char* klass_name = method->method_holder()->name()->as_utf8();
928 const char* method_name = method->name()->as_utf8();
929 const char* signature = method->signature()->as_utf8();
930 for (int i = 0; i < records->length(); i++) {
931 ciInlineRecord* rec = records->at(i);
932 if ((rec->_inline_bci == bci) &&
933 (rec->_inline_depth == depth) &&
934 (strcmp(rec->_klass_name, klass_name) == 0) &&
935 (strcmp(rec->_method_name, method_name) == 0) &&
936 (strcmp(rec->_signature, signature) == 0)) {
937 return rec;
938 }
776 } 939 }
777 } 940 }
778 return NULL; 941 return NULL;
779 } 942 }
780 943
782 return _error_message; 945 return _error_message;
783 } 946 }
784 947
785 void reset() { 948 void reset() {
786 _error_message = NULL; 949 _error_message = NULL;
787 ci_method_records.clear(); 950 _ci_method_records.clear();
788 ci_method_data_records.clear(); 951 _ci_method_data_records.clear();
789 } 952 }
790 953
791 // Take an ascii string contain \u#### escapes and convert it to utf8 954 // Take an ascii string contain \u#### escapes and convert it to utf8
792 // in place. 955 // in place.
793 static void unescape_string(char* value) { 956 static void unescape_string(char* value) {
843 Threads::destroy_vm(); 1006 Threads::destroy_vm();
844 1007
845 vm_exit(exit_code); 1008 vm_exit(exit_code);
846 } 1009 }
847 1010
1011 void* ciReplay::load_inline_data(ciMethod* method, int entry_bci, int comp_level) {
1012 if (FLAG_IS_DEFAULT(InlineDataFile)) {
1013 tty->print_cr("ERROR: no inline replay data file specified (use -XX:InlineDataFile=inline_pid12345.txt).");
1014 return NULL;
1015 }
1016
1017 VM_ENTRY_MARK;
1018 // Load and parse the replay data
1019 CompileReplay rp(InlineDataFile, THREAD);
1020 if (!rp.can_replay()) {
1021 tty->print_cr("ciReplay: !rp.can_replay()");
1022 return NULL;
1023 }
1024 void* data = rp.process_inline(method, method->get_Method(), entry_bci, comp_level, THREAD);
1025 if (HAS_PENDING_EXCEPTION) {
1026 oop throwable = PENDING_EXCEPTION;
1027 CLEAR_PENDING_EXCEPTION;
1028 java_lang_Throwable::print(throwable, tty);
1029 tty->cr();
1030 java_lang_Throwable::print_stack_trace(throwable, tty);
1031 tty->cr();
1032 return NULL;
1033 }
1034
1035 if (rp.had_error()) {
1036 tty->print_cr("ciReplay: Failed on %s", rp.error_message());
1037 return NULL;
1038 }
1039 return data;
1040 }
1041
848 int ciReplay::replay_impl(TRAPS) { 1042 int ciReplay::replay_impl(TRAPS) {
849 HandleMark hm; 1043 HandleMark hm;
850 ResourceMark rm; 1044 ResourceMark rm;
851 // Make sure we don't run with background compilation 1045 // Make sure we don't run with background compilation
852 BackgroundCompilation = false; 1046 BackgroundCompilation = false;
887 tty->print_cr("Failed on %s", rp.error_message()); 1081 tty->print_cr("Failed on %s", rp.error_message());
888 exit_code = 1; 1082 exit_code = 1;
889 } 1083 }
890 return exit_code; 1084 return exit_code;
891 } 1085 }
892
893 1086
894 void ciReplay::initialize(ciMethodData* m) { 1087 void ciReplay::initialize(ciMethodData* m) {
895 if (replay_state == NULL) { 1088 if (replay_state == NULL) {
896 return; 1089 return;
897 } 1090 }
907 // interfere with reproducing a bug 1100 // interfere with reproducing a bug
908 tty->print_cr("Warning: requesting ciMethodData record for method with no data: "); 1101 tty->print_cr("Warning: requesting ciMethodData record for method with no data: ");
909 method->print_name(tty); 1102 method->print_name(tty);
910 tty->cr(); 1103 tty->cr();
911 } else { 1104 } else {
912 m->_state = rec->state; 1105 m->_state = rec->_state;
913 m->_current_mileage = rec->current_mileage; 1106 m->_current_mileage = rec->_current_mileage;
914 if (rec->data_length != 0) { 1107 if (rec->_data_length != 0) {
915 assert(m->_data_size == rec->data_length * (int)sizeof(rec->data[0]), "must agree"); 1108 assert(m->_data_size == rec->_data_length * (int)sizeof(rec->_data[0]), "must agree");
916 1109
917 // Write the correct ciObjects back into the profile data 1110 // Write the correct ciObjects back into the profile data
918 ciEnv* env = ciEnv::current(); 1111 ciEnv* env = ciEnv::current();
919 for (int i = 0; i < rec->oops_length; i++) { 1112 for (int i = 0; i < rec->_oops_length; i++) {
920 KlassHandle *h = (KlassHandle *)rec->oops_handles[i]; 1113 KlassHandle *h = (KlassHandle *)rec->_oops_handles[i];
921 *(ciMetadata**)(rec->data + rec->oops_offsets[i]) = 1114 *(ciMetadata**)(rec->_data + rec->_oops_offsets[i]) =
922 env->get_metadata((*h)()); 1115 env->get_metadata((*h)());
923 } 1116 }
924 // Copy the updated profile data into place as intptr_ts 1117 // Copy the updated profile data into place as intptr_ts
925 #ifdef _LP64 1118 #ifdef _LP64
926 Copy::conjoint_jlongs_atomic((jlong *)rec->data, (jlong *)m->_data, rec->data_length); 1119 Copy::conjoint_jlongs_atomic((jlong *)rec->_data, (jlong *)m->_data, rec->_data_length);
927 #else 1120 #else
928 Copy::conjoint_jints_atomic((jint *)rec->data, (jint *)m->_data, rec->data_length); 1121 Copy::conjoint_jints_atomic((jint *)rec->_data, (jint *)m->_data, rec->_data_length);
929 #endif 1122 #endif
930 } 1123 }
931 1124
932 // copy in the original header 1125 // copy in the original header
933 Copy::conjoint_jbytes(rec->orig_data, (char*)&m->_orig, rec->orig_data_length); 1126 Copy::conjoint_jbytes(rec->_orig_data, (char*)&m->_orig, rec->_orig_data_length);
934 } 1127 }
935 } 1128 }
936 1129
937 1130
938 bool ciReplay::should_not_inline(ciMethod* method) { 1131 bool ciReplay::should_not_inline(ciMethod* method) {
939 if (replay_state == NULL) { 1132 if (replay_state == NULL) {
940 return false; 1133 return false;
941 } 1134 }
942
943 VM_ENTRY_MARK; 1135 VM_ENTRY_MARK;
944 // ciMethod without a record shouldn't be inlined. 1136 // ciMethod without a record shouldn't be inlined.
945 return replay_state->find_ciMethodRecord(method->get_Method()) == NULL; 1137 return replay_state->find_ciMethodRecord(method->get_Method()) == NULL;
946 } 1138 }
947 1139
1140 bool ciReplay::should_inline(void* data, ciMethod* method, int bci, int inline_depth) {
1141 if (data != NULL) {
1142 GrowableArray<ciInlineRecord*>* records = (GrowableArray<ciInlineRecord*>*)data;
1143 VM_ENTRY_MARK;
1144 // Inline record are ordered by bci and depth.
1145 return CompileReplay::find_ciInlineRecord(records, method->get_Method(), bci, inline_depth) != NULL;
1146 } else if (replay_state != NULL) {
1147 VM_ENTRY_MARK;
1148 // Inline record are ordered by bci and depth.
1149 return replay_state->find_ciInlineRecord(method->get_Method(), bci, inline_depth) != NULL;
1150 }
1151 return false;
1152 }
1153
1154 bool ciReplay::should_not_inline(void* data, ciMethod* method, int bci, int inline_depth) {
1155 if (data != NULL) {
1156 GrowableArray<ciInlineRecord*>* records = (GrowableArray<ciInlineRecord*>*)data;
1157 VM_ENTRY_MARK;
1158 // Inline record are ordered by bci and depth.
1159 return CompileReplay::find_ciInlineRecord(records, method->get_Method(), bci, inline_depth) == NULL;
1160 } else if (replay_state != NULL) {
1161 VM_ENTRY_MARK;
1162 // Inline record are ordered by bci and depth.
1163 return replay_state->find_ciInlineRecord(method->get_Method(), bci, inline_depth) == NULL;
1164 }
1165 return false;
1166 }
948 1167
949 void ciReplay::initialize(ciMethod* m) { 1168 void ciReplay::initialize(ciMethod* m) {
950 if (replay_state == NULL) { 1169 if (replay_state == NULL) {
951 return; 1170 return;
952 } 1171 }
963 tty->print_cr("Warning: requesting ciMethod record for method with no data: "); 1182 tty->print_cr("Warning: requesting ciMethod record for method with no data: ");
964 method->print_name(tty); 1183 method->print_name(tty);
965 tty->cr(); 1184 tty->cr();
966 } else { 1185 } else {
967 EXCEPTION_CONTEXT; 1186 EXCEPTION_CONTEXT;
968 // m->_instructions_size = rec->instructions_size; 1187 // m->_instructions_size = rec->_instructions_size;
969 m->_instructions_size = -1; 1188 m->_instructions_size = -1;
970 m->_interpreter_invocation_count = rec->interpreter_invocation_count; 1189 m->_interpreter_invocation_count = rec->_interpreter_invocation_count;
971 m->_interpreter_throwout_count = rec->interpreter_throwout_count; 1190 m->_interpreter_throwout_count = rec->_interpreter_throwout_count;
972 MethodCounters* mcs = method->get_method_counters(CHECK_AND_CLEAR); 1191 MethodCounters* mcs = method->get_method_counters(CHECK_AND_CLEAR);
973 guarantee(mcs != NULL, "method counters allocation failed"); 1192 guarantee(mcs != NULL, "method counters allocation failed");
974 mcs->invocation_counter()->_counter = rec->invocation_counter; 1193 mcs->invocation_counter()->_counter = rec->_invocation_counter;
975 mcs->backedge_counter()->_counter = rec->backedge_counter; 1194 mcs->backedge_counter()->_counter = rec->_backedge_counter;
976 } 1195 }
977 } 1196 }
978 1197
979 bool ciReplay::is_loaded(Method* method) { 1198 bool ciReplay::is_loaded(Method* method) {
980 if (replay_state == NULL) { 1199 if (replay_state == NULL) {