comparison src/share/vm/ci/ciReplay.cpp @ 14518:d8041d695d19

Merged with jdk9/dev/hotspot changeset 3812c088b945
author twisti
date Tue, 11 Mar 2014 18:45:59 -0700
parents 183bd5c00828
children 4ca6dc0799b6 653e11c86c5a
comparison
equal deleted inserted replaced
14141:f97c5ec83832 14518:d8041d695d19
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(CHECK);
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 tty->print_cr("%s", _buffer);
319 buffer_length = newl; 383 return;
320 } 384 }
321 if (c == '\n') { 385 line_no++;
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;
331 }
332 pos = 0;
333 buffer_end = 0;
334 line_no++;
335 } else if (c == '\r') {
336 // skip LF
337 } else {
338 buffer[pos++] = c;
339 }
340 c = getc(stream);
341 } 386 }
342 } 387 }
343 388
344 void process_command(TRAPS) { 389 void process_command(TRAPS) {
345 char* cmd = parse_string(); 390 char* cmd = parse_string();
394 return false; 439 return false;
395 } 440 }
396 return true; 441 return true;
397 } 442 }
398 443
399 // compile <klass> <name> <signature> <entry_bci> <comp_level> 444 // compile <klass> <name> <signature> <entry_bci> <comp_level> inline <count> <depth> <bci> <klass> <name> <signature> ...
445 void* process_inline(ciMethod* imethod, Method* m, int entry_bci, int comp_level, TRAPS) {
446 _imethod = m;
447 _iklass = imethod->holder();
448 _entry_bci = entry_bci;
449 _comp_level = comp_level;
450 int line_no = 1;
451 int c = getc(_stream);
452 while(c != EOF) {
453 c = get_line(c);
454 // Expecting only lines with "compile" command in inline replay file.
455 char* cmd = parse_string();
456 if (cmd == NULL || strcmp("compile", cmd) != 0) {
457 return NULL;
458 }
459 process_compile(CHECK_NULL);
460 if (had_error()) {
461 tty->print_cr("Error while parsing line %d: %s\n", line_no, _error_message);
462 tty->print_cr("%s", _buffer);
463 return NULL;
464 }
465 if (_ci_inline_records != NULL && _ci_inline_records->length() > 0) {
466 // Found inlining record for the requested method.
467 return _ci_inline_records;
468 }
469 line_no++;
470 }
471 return NULL;
472 }
473
474 // compile <klass> <name> <signature> <entry_bci> <comp_level> inline <count> <depth> <bci> <klass> <name> <signature> ...
400 void process_compile(TRAPS) { 475 void process_compile(TRAPS) {
401 Method* method = parse_method(CHECK); 476 Method* method = parse_method(CHECK);
402 if (had_error()) return; 477 if (had_error()) return;
403 int entry_bci = parse_int("entry_bci"); 478 int entry_bci = parse_int("entry_bci");
404 const char* comp_level_label = "comp_level"; 479 const char* comp_level_label = "comp_level";
407 if (had_error() && (error_message() == comp_level_label)) { 482 if (had_error() && (error_message() == comp_level_label)) {
408 comp_level = CompLevel_full_optimization; 483 comp_level = CompLevel_full_optimization;
409 } 484 }
410 if (!is_valid_comp_level(comp_level)) { 485 if (!is_valid_comp_level(comp_level)) {
411 return; 486 return;
487 }
488 if (_imethod != NULL) {
489 // Replay Inlining
490 if (entry_bci != _entry_bci || comp_level != _comp_level) {
491 return;
492 }
493 const char* iklass_name = _imethod->method_holder()->name()->as_utf8();
494 const char* imethod_name = _imethod->name()->as_utf8();
495 const char* isignature = _imethod->signature()->as_utf8();
496 const char* klass_name = method->method_holder()->name()->as_utf8();
497 const char* method_name = method->name()->as_utf8();
498 const char* signature = method->signature()->as_utf8();
499 if (strcmp(iklass_name, klass_name) != 0 ||
500 strcmp(imethod_name, method_name) != 0 ||
501 strcmp(isignature, signature) != 0) {
502 return;
503 }
504 }
505 int inline_count = 0;
506 if (parse_tag_and_count("inline", inline_count)) {
507 // Record inlining data
508 _ci_inline_records = new GrowableArray<ciInlineRecord*>();
509 for (int i = 0; i < inline_count; i++) {
510 int depth = parse_int("inline_depth");
511 int bci = parse_int("inline_bci");
512 if (had_error()) {
513 break;
514 }
515 Method* inl_method = parse_method(CHECK);
516 if (had_error()) {
517 break;
518 }
519 new_ciInlineRecord(inl_method, bci, depth);
520 }
521 }
522 if (_imethod != NULL) {
523 return; // Replay Inlining
412 } 524 }
413 Klass* k = method->method_holder(); 525 Klass* k = method->method_holder();
414 ((InstanceKlass*)k)->initialize(THREAD); 526 ((InstanceKlass*)k)->initialize(THREAD);
415 if (HAS_PENDING_EXCEPTION) { 527 if (HAS_PENDING_EXCEPTION) {
416 oop throwable = PENDING_EXCEPTION; 528 oop throwable = PENDING_EXCEPTION;
440 // 552 //
441 void process_ciMethod(TRAPS) { 553 void process_ciMethod(TRAPS) {
442 Method* method = parse_method(CHECK); 554 Method* method = parse_method(CHECK);
443 if (had_error()) return; 555 if (had_error()) return;
444 ciMethodRecord* rec = new_ciMethod(method); 556 ciMethodRecord* rec = new_ciMethod(method);
445 rec->invocation_counter = parse_int("invocation_counter"); 557 rec->_invocation_counter = parse_int("invocation_counter");
446 rec->backedge_counter = parse_int("backedge_counter"); 558 rec->_backedge_counter = parse_int("backedge_counter");
447 rec->interpreter_invocation_count = parse_int("interpreter_invocation_count"); 559 rec->_interpreter_invocation_count = parse_int("interpreter_invocation_count");
448 rec->interpreter_throwout_count = parse_int("interpreter_throwout_count"); 560 rec->_interpreter_throwout_count = parse_int("interpreter_throwout_count");
449 rec->instructions_size = parse_int("instructions_size"); 561 rec->_instructions_size = parse_int("instructions_size");
450 } 562 }
451 563
452 // ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length> 564 // ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length>
453 void process_ciMethodData(TRAPS) { 565 void process_ciMethodData(TRAPS) {
454 Method* method = parse_method(CHECK); 566 Method* method = parse_method(CHECK);
469 } 581 }
470 } 582 }
471 583
472 // collect and record all the needed information for later 584 // collect and record all the needed information for later
473 ciMethodDataRecord* rec = new_ciMethodData(method); 585 ciMethodDataRecord* rec = new_ciMethodData(method);
474 rec->state = parse_int("state"); 586 rec->_state = parse_int("state");
475 rec->current_mileage = parse_int("current_mileage"); 587 rec->_current_mileage = parse_int("current_mileage");
476 588
477 rec->orig_data = parse_data("orig", rec->orig_data_length); 589 rec->_orig_data = parse_data("orig", rec->_orig_data_length);
478 if (rec->orig_data == NULL) { 590 if (rec->_orig_data == NULL) {
479 return; 591 return;
480 } 592 }
481 rec->data = parse_intptr_data("data", rec->data_length); 593 rec->_data = parse_intptr_data("data", rec->_data_length);
482 if (rec->data == NULL) { 594 if (rec->_data == NULL) {
483 return; 595 return;
484 } 596 }
485 if (!parse_tag_and_count("oops", rec->oops_length)) { 597 if (!parse_tag_and_count("oops", rec->_oops_length)) {
486 return; 598 return;
487 } 599 }
488 rec->oops_handles = NEW_RESOURCE_ARRAY(jobject, rec->oops_length); 600 rec->_oops_handles = NEW_RESOURCE_ARRAY(jobject, rec->_oops_length);
489 rec->oops_offsets = NEW_RESOURCE_ARRAY(int, rec->oops_length); 601 rec->_oops_offsets = NEW_RESOURCE_ARRAY(int, rec->_oops_length);
490 for (int i = 0; i < rec->oops_length; i++) { 602 for (int i = 0; i < rec->_oops_length; i++) {
491 int offset = parse_int("offset"); 603 int offset = parse_int("offset");
492 if (had_error()) { 604 if (had_error()) {
493 return; 605 return;
494 } 606 }
495 Klass* k = parse_klass(CHECK); 607 Klass* k = parse_klass(CHECK);
496 rec->oops_offsets[i] = offset; 608 rec->_oops_offsets[i] = offset;
497 KlassHandle *kh = NEW_C_HEAP_OBJ(KlassHandle, mtCompiler); 609 KlassHandle *kh = NEW_C_HEAP_OBJ(KlassHandle, mtCompiler);
498 ::new ((void*)kh) KlassHandle(THREAD, k); 610 ::new ((void*)kh) KlassHandle(THREAD, k);
499 rec->oops_handles[i] = (jobject)kh; 611 rec->_oops_handles[i] = (jobject)kh;
500 } 612 }
501 } 613 }
502 614
503 // instanceKlass <name> 615 // instanceKlass <name>
504 // 616 //
568 case JVM_CONSTANT_InterfaceMethodref: 680 case JVM_CONSTANT_InterfaceMethodref:
569 case JVM_CONSTANT_NameAndType: 681 case JVM_CONSTANT_NameAndType:
570 case JVM_CONSTANT_Utf8: 682 case JVM_CONSTANT_Utf8:
571 case JVM_CONSTANT_Integer: 683 case JVM_CONSTANT_Integer:
572 case JVM_CONSTANT_Float: 684 case JVM_CONSTANT_Float:
685 case JVM_CONSTANT_MethodHandle:
686 case JVM_CONSTANT_MethodType:
687 case JVM_CONSTANT_InvokeDynamic:
573 if (tag != cp->tag_at(i).value()) { 688 if (tag != cp->tag_at(i).value()) {
574 report_error("tag mismatch: wrong class files?"); 689 report_error("tag mismatch: wrong class files?");
575 return; 690 return;
576 } 691 }
577 break; 692 break;
727 #endif // INCLUDE_JVMTI 842 #endif // INCLUDE_JVMTI
728 843
729 // Create and initialize a record for a ciMethod 844 // Create and initialize a record for a ciMethod
730 ciMethodRecord* new_ciMethod(Method* method) { 845 ciMethodRecord* new_ciMethod(Method* method) {
731 ciMethodRecord* rec = NEW_RESOURCE_OBJ(ciMethodRecord); 846 ciMethodRecord* rec = NEW_RESOURCE_OBJ(ciMethodRecord);
732 rec->klass = method->method_holder()->name()->as_utf8(); 847 rec->_klass_name = method->method_holder()->name()->as_utf8();
733 rec->method = method->name()->as_utf8(); 848 rec->_method_name = method->name()->as_utf8();
734 rec->signature = method->signature()->as_utf8(); 849 rec->_signature = method->signature()->as_utf8();
735 ci_method_records.append(rec); 850 _ci_method_records.append(rec);
736 return rec; 851 return rec;
737 } 852 }
738 853
739 // Lookup data for a ciMethod 854 // Lookup data for a ciMethod
740 ciMethodRecord* find_ciMethodRecord(Method* method) { 855 ciMethodRecord* find_ciMethodRecord(Method* method) {
741 const char* klass_name = method->method_holder()->name()->as_utf8(); 856 const char* klass_name = method->method_holder()->name()->as_utf8();
742 const char* method_name = method->name()->as_utf8(); 857 const char* method_name = method->name()->as_utf8();
743 const char* signature = method->signature()->as_utf8(); 858 const char* signature = method->signature()->as_utf8();
744 for (int i = 0; i < ci_method_records.length(); i++) { 859 for (int i = 0; i < _ci_method_records.length(); i++) {
745 ciMethodRecord* rec = ci_method_records.at(i); 860 ciMethodRecord* rec = _ci_method_records.at(i);
746 if (strcmp(rec->klass, klass_name) == 0 && 861 if (strcmp(rec->_klass_name, klass_name) == 0 &&
747 strcmp(rec->method, method_name) == 0 && 862 strcmp(rec->_method_name, method_name) == 0 &&
748 strcmp(rec->signature, signature) == 0) { 863 strcmp(rec->_signature, signature) == 0) {
749 return rec; 864 return rec;
750 } 865 }
751 } 866 }
752 return NULL; 867 return NULL;
753 } 868 }
754 869
755 // Create and initialize a record for a ciMethodData 870 // Create and initialize a record for a ciMethodData
756 ciMethodDataRecord* new_ciMethodData(Method* method) { 871 ciMethodDataRecord* new_ciMethodData(Method* method) {
757 ciMethodDataRecord* rec = NEW_RESOURCE_OBJ(ciMethodDataRecord); 872 ciMethodDataRecord* rec = NEW_RESOURCE_OBJ(ciMethodDataRecord);
758 rec->klass = method->method_holder()->name()->as_utf8(); 873 rec->_klass_name = method->method_holder()->name()->as_utf8();
759 rec->method = method->name()->as_utf8(); 874 rec->_method_name = method->name()->as_utf8();
760 rec->signature = method->signature()->as_utf8(); 875 rec->_signature = method->signature()->as_utf8();
761 ci_method_data_records.append(rec); 876 _ci_method_data_records.append(rec);
762 return rec; 877 return rec;
763 } 878 }
764 879
765 // Lookup data for a ciMethodData 880 // Lookup data for a ciMethodData
766 ciMethodDataRecord* find_ciMethodDataRecord(Method* method) { 881 ciMethodDataRecord* find_ciMethodDataRecord(Method* method) {
767 const char* klass_name = method->method_holder()->name()->as_utf8(); 882 const char* klass_name = method->method_holder()->name()->as_utf8();
768 const char* method_name = method->name()->as_utf8(); 883 const char* method_name = method->name()->as_utf8();
769 const char* signature = method->signature()->as_utf8(); 884 const char* signature = method->signature()->as_utf8();
770 for (int i = 0; i < ci_method_data_records.length(); i++) { 885 for (int i = 0; i < _ci_method_data_records.length(); i++) {
771 ciMethodDataRecord* rec = ci_method_data_records.at(i); 886 ciMethodDataRecord* rec = _ci_method_data_records.at(i);
772 if (strcmp(rec->klass, klass_name) == 0 && 887 if (strcmp(rec->_klass_name, klass_name) == 0 &&
773 strcmp(rec->method, method_name) == 0 && 888 strcmp(rec->_method_name, method_name) == 0 &&
774 strcmp(rec->signature, signature) == 0) { 889 strcmp(rec->_signature, signature) == 0) {
775 return rec; 890 return rec;
891 }
892 }
893 return NULL;
894 }
895
896 // Create and initialize a record for a ciInlineRecord
897 ciInlineRecord* new_ciInlineRecord(Method* method, int bci, int depth) {
898 ciInlineRecord* rec = NEW_RESOURCE_OBJ(ciInlineRecord);
899 rec->_klass_name = method->method_holder()->name()->as_utf8();
900 rec->_method_name = method->name()->as_utf8();
901 rec->_signature = method->signature()->as_utf8();
902 rec->_inline_bci = bci;
903 rec->_inline_depth = depth;
904 _ci_inline_records->append(rec);
905 return rec;
906 }
907
908 // Lookup inlining data for a ciMethod
909 ciInlineRecord* find_ciInlineRecord(Method* method, int bci, int depth) {
910 if (_ci_inline_records != NULL) {
911 return find_ciInlineRecord(_ci_inline_records, method, bci, depth);
912 }
913 return NULL;
914 }
915
916 static ciInlineRecord* find_ciInlineRecord(GrowableArray<ciInlineRecord*>* records,
917 Method* method, int bci, int depth) {
918 if (records != NULL) {
919 const char* klass_name = method->method_holder()->name()->as_utf8();
920 const char* method_name = method->name()->as_utf8();
921 const char* signature = method->signature()->as_utf8();
922 for (int i = 0; i < records->length(); i++) {
923 ciInlineRecord* rec = records->at(i);
924 if ((rec->_inline_bci == bci) &&
925 (rec->_inline_depth == depth) &&
926 (strcmp(rec->_klass_name, klass_name) == 0) &&
927 (strcmp(rec->_method_name, method_name) == 0) &&
928 (strcmp(rec->_signature, signature) == 0)) {
929 return rec;
930 }
776 } 931 }
777 } 932 }
778 return NULL; 933 return NULL;
779 } 934 }
780 935
782 return _error_message; 937 return _error_message;
783 } 938 }
784 939
785 void reset() { 940 void reset() {
786 _error_message = NULL; 941 _error_message = NULL;
787 ci_method_records.clear(); 942 _ci_method_records.clear();
788 ci_method_data_records.clear(); 943 _ci_method_data_records.clear();
789 } 944 }
790 945
791 // Take an ascii string contain \u#### escapes and convert it to utf8 946 // Take an ascii string contain \u#### escapes and convert it to utf8
792 // in place. 947 // in place.
793 static void unescape_string(char* value) { 948 static void unescape_string(char* value) {
843 Threads::destroy_vm(); 998 Threads::destroy_vm();
844 999
845 vm_exit(exit_code); 1000 vm_exit(exit_code);
846 } 1001 }
847 1002
1003 void* ciReplay::load_inline_data(ciMethod* method, int entry_bci, int comp_level) {
1004 if (FLAG_IS_DEFAULT(InlineDataFile)) {
1005 tty->print_cr("ERROR: no inline replay data file specified (use -XX:InlineDataFile=inline_pid12345.txt).");
1006 return NULL;
1007 }
1008
1009 VM_ENTRY_MARK;
1010 // Load and parse the replay data
1011 CompileReplay rp(InlineDataFile, THREAD);
1012 if (!rp.can_replay()) {
1013 tty->print_cr("ciReplay: !rp.can_replay()");
1014 return NULL;
1015 }
1016 void* data = rp.process_inline(method, method->get_Method(), entry_bci, comp_level, THREAD);
1017 if (HAS_PENDING_EXCEPTION) {
1018 oop throwable = PENDING_EXCEPTION;
1019 CLEAR_PENDING_EXCEPTION;
1020 java_lang_Throwable::print(throwable, tty);
1021 tty->cr();
1022 java_lang_Throwable::print_stack_trace(throwable, tty);
1023 tty->cr();
1024 return NULL;
1025 }
1026
1027 if (rp.had_error()) {
1028 tty->print_cr("ciReplay: Failed on %s", rp.error_message());
1029 return NULL;
1030 }
1031 return data;
1032 }
1033
848 int ciReplay::replay_impl(TRAPS) { 1034 int ciReplay::replay_impl(TRAPS) {
849 HandleMark hm; 1035 HandleMark hm;
850 ResourceMark rm; 1036 ResourceMark rm;
851 // Make sure we don't run with background compilation 1037 // Make sure we don't run with background compilation
852 BackgroundCompilation = false; 1038 BackgroundCompilation = false;
887 tty->print_cr("Failed on %s", rp.error_message()); 1073 tty->print_cr("Failed on %s", rp.error_message());
888 exit_code = 1; 1074 exit_code = 1;
889 } 1075 }
890 return exit_code; 1076 return exit_code;
891 } 1077 }
892
893 1078
894 void ciReplay::initialize(ciMethodData* m) { 1079 void ciReplay::initialize(ciMethodData* m) {
895 if (replay_state == NULL) { 1080 if (replay_state == NULL) {
896 return; 1081 return;
897 } 1082 }
907 // interfere with reproducing a bug 1092 // interfere with reproducing a bug
908 tty->print_cr("Warning: requesting ciMethodData record for method with no data: "); 1093 tty->print_cr("Warning: requesting ciMethodData record for method with no data: ");
909 method->print_name(tty); 1094 method->print_name(tty);
910 tty->cr(); 1095 tty->cr();
911 } else { 1096 } else {
912 m->_state = rec->state; 1097 m->_state = rec->_state;
913 m->_current_mileage = rec->current_mileage; 1098 m->_current_mileage = rec->_current_mileage;
914 if (rec->data_length != 0) { 1099 if (rec->_data_length != 0) {
915 assert(m->_data_size == rec->data_length * (int)sizeof(rec->data[0]), "must agree"); 1100 assert(m->_data_size == rec->_data_length * (int)sizeof(rec->_data[0]), "must agree");
916 1101
917 // Write the correct ciObjects back into the profile data 1102 // Write the correct ciObjects back into the profile data
918 ciEnv* env = ciEnv::current(); 1103 ciEnv* env = ciEnv::current();
919 for (int i = 0; i < rec->oops_length; i++) { 1104 for (int i = 0; i < rec->_oops_length; i++) {
920 KlassHandle *h = (KlassHandle *)rec->oops_handles[i]; 1105 KlassHandle *h = (KlassHandle *)rec->_oops_handles[i];
921 *(ciMetadata**)(rec->data + rec->oops_offsets[i]) = 1106 *(ciMetadata**)(rec->_data + rec->_oops_offsets[i]) =
922 env->get_metadata((*h)()); 1107 env->get_metadata((*h)());
923 } 1108 }
924 // Copy the updated profile data into place as intptr_ts 1109 // Copy the updated profile data into place as intptr_ts
925 #ifdef _LP64 1110 #ifdef _LP64
926 Copy::conjoint_jlongs_atomic((jlong *)rec->data, (jlong *)m->_data, rec->data_length); 1111 Copy::conjoint_jlongs_atomic((jlong *)rec->_data, (jlong *)m->_data, rec->_data_length);
927 #else 1112 #else
928 Copy::conjoint_jints_atomic((jint *)rec->data, (jint *)m->_data, rec->data_length); 1113 Copy::conjoint_jints_atomic((jint *)rec->_data, (jint *)m->_data, rec->_data_length);
929 #endif 1114 #endif
930 } 1115 }
931 1116
932 // copy in the original header 1117 // copy in the original header
933 Copy::conjoint_jbytes(rec->orig_data, (char*)&m->_orig, rec->orig_data_length); 1118 Copy::conjoint_jbytes(rec->_orig_data, (char*)&m->_orig, rec->_orig_data_length);
934 } 1119 }
935 } 1120 }
936 1121
937 1122
938 bool ciReplay::should_not_inline(ciMethod* method) { 1123 bool ciReplay::should_not_inline(ciMethod* method) {
939 if (replay_state == NULL) { 1124 if (replay_state == NULL) {
940 return false; 1125 return false;
941 } 1126 }
942
943 VM_ENTRY_MARK; 1127 VM_ENTRY_MARK;
944 // ciMethod without a record shouldn't be inlined. 1128 // ciMethod without a record shouldn't be inlined.
945 return replay_state->find_ciMethodRecord(method->get_Method()) == NULL; 1129 return replay_state->find_ciMethodRecord(method->get_Method()) == NULL;
946 } 1130 }
947 1131
1132 bool ciReplay::should_inline(void* data, ciMethod* method, int bci, int inline_depth) {
1133 if (data != NULL) {
1134 GrowableArray<ciInlineRecord*>* records = (GrowableArray<ciInlineRecord*>*)data;
1135 VM_ENTRY_MARK;
1136 // Inline record are ordered by bci and depth.
1137 return CompileReplay::find_ciInlineRecord(records, method->get_Method(), bci, inline_depth) != NULL;
1138 } else if (replay_state != NULL) {
1139 VM_ENTRY_MARK;
1140 // Inline record are ordered by bci and depth.
1141 return replay_state->find_ciInlineRecord(method->get_Method(), bci, inline_depth) != NULL;
1142 }
1143 return false;
1144 }
1145
1146 bool ciReplay::should_not_inline(void* data, ciMethod* method, int bci, int inline_depth) {
1147 if (data != NULL) {
1148 GrowableArray<ciInlineRecord*>* records = (GrowableArray<ciInlineRecord*>*)data;
1149 VM_ENTRY_MARK;
1150 // Inline record are ordered by bci and depth.
1151 return CompileReplay::find_ciInlineRecord(records, method->get_Method(), bci, inline_depth) == NULL;
1152 } else if (replay_state != NULL) {
1153 VM_ENTRY_MARK;
1154 // Inline record are ordered by bci and depth.
1155 return replay_state->find_ciInlineRecord(method->get_Method(), bci, inline_depth) == NULL;
1156 }
1157 return false;
1158 }
948 1159
949 void ciReplay::initialize(ciMethod* m) { 1160 void ciReplay::initialize(ciMethod* m) {
950 if (replay_state == NULL) { 1161 if (replay_state == NULL) {
951 return; 1162 return;
952 } 1163 }
963 tty->print_cr("Warning: requesting ciMethod record for method with no data: "); 1174 tty->print_cr("Warning: requesting ciMethod record for method with no data: ");
964 method->print_name(tty); 1175 method->print_name(tty);
965 tty->cr(); 1176 tty->cr();
966 } else { 1177 } else {
967 EXCEPTION_CONTEXT; 1178 EXCEPTION_CONTEXT;
968 // m->_instructions_size = rec->instructions_size; 1179 // m->_instructions_size = rec->_instructions_size;
969 m->_instructions_size = -1; 1180 m->_instructions_size = -1;
970 m->_interpreter_invocation_count = rec->interpreter_invocation_count; 1181 m->_interpreter_invocation_count = rec->_interpreter_invocation_count;
971 m->_interpreter_throwout_count = rec->interpreter_throwout_count; 1182 m->_interpreter_throwout_count = rec->_interpreter_throwout_count;
972 MethodCounters* mcs = method->get_method_counters(CHECK_AND_CLEAR); 1183 MethodCounters* mcs = method->get_method_counters(CHECK_AND_CLEAR);
973 guarantee(mcs != NULL, "method counters allocation failed"); 1184 guarantee(mcs != NULL, "method counters allocation failed");
974 mcs->invocation_counter()->_counter = rec->invocation_counter; 1185 mcs->invocation_counter()->_counter = rec->_invocation_counter;
975 mcs->backedge_counter()->_counter = rec->backedge_counter; 1186 mcs->backedge_counter()->_counter = rec->_backedge_counter;
976 } 1187 }
977 } 1188 }
978 1189
979 bool ciReplay::is_loaded(Method* method) { 1190 bool ciReplay::is_loaded(Method* method) {
980 if (replay_state == NULL) { 1191 if (replay_state == NULL) {