29 |
29 |
30 package com.sun.hotspot.tools.compiler; |
30 package com.sun.hotspot.tools.compiler; |
31 |
31 |
32 import java.io.FileReader; |
32 import java.io.FileReader; |
33 import java.io.Reader; |
33 import java.io.Reader; |
|
34 import java.util.ArrayDeque; |
34 import java.util.ArrayList; |
35 import java.util.ArrayList; |
35 import java.util.Collections; |
36 import java.util.Collections; |
36 import java.util.Comparator; |
37 import java.util.Comparator; |
37 import java.util.HashMap; |
38 import java.util.HashMap; |
38 import java.util.LinkedHashMap; |
39 import java.util.LinkedHashMap; |
142 private String failureReason; |
143 private String failureReason; |
143 private int bci; |
144 private int bci; |
144 private Stack<CallSite> scopes = new Stack<CallSite>(); |
145 private Stack<CallSite> scopes = new Stack<CallSite>(); |
145 private Compilation compile; |
146 private Compilation compile; |
146 private CallSite site; |
147 private CallSite site; |
|
148 private CallSite methodHandleSite; |
147 private Stack<Phase> phaseStack = new Stack<Phase>(); |
149 private Stack<Phase> phaseStack = new Stack<Phase>(); |
148 private UncommonTrapEvent currentTrap; |
150 private UncommonTrapEvent currentTrap; |
149 private Stack<CallSite> late_inline_scope; |
151 private Stack<CallSite> lateInlineScope; |
|
152 private boolean lateInlining; |
|
153 |
150 |
154 |
151 long parseLong(String l) { |
155 long parseLong(String l) { |
152 try { |
156 try { |
153 return Long.decode(l).longValue(); |
157 return Long.decode(l).longValue(); |
154 } catch (NumberFormatException nfe) { |
158 } catch (NumberFormatException nfe) { |
328 m.setIICount(search(atts, "iicount")); |
332 m.setIICount(search(atts, "iicount")); |
329 m.setFlags(search(atts, "flags")); |
333 m.setFlags(search(atts, "flags")); |
330 } |
334 } |
331 methods.put(id, m); |
335 methods.put(id, m); |
332 } else if (qname.equals("call")) { |
336 } else if (qname.equals("call")) { |
333 site = new CallSite(bci, method(search(atts, "method"))); |
337 if (methodHandleSite != null) { |
|
338 methodHandleSite = null; |
|
339 } |
|
340 Method m = method(search(atts, "method")); |
|
341 if (lateInlining && scopes.size() == 0) { |
|
342 // re-attempting already seen call site (late inlining for MH invokes) |
|
343 if (m != site.getMethod()) { |
|
344 if (bci != site.getBci()) { |
|
345 System.out.println(m + " bci: " + bci); |
|
346 System.out.println(site.getMethod() + " bci: " + site.getBci()); |
|
347 throw new InternalError("bci mismatch after late inlining"); |
|
348 } |
|
349 site.setMethod(m); |
|
350 } |
|
351 } else { |
|
352 site = new CallSite(bci, m); |
|
353 } |
334 site.setCount(Integer.parseInt(search(atts, "count", "0"))); |
354 site.setCount(Integer.parseInt(search(atts, "count", "0"))); |
335 String receiver = atts.getValue("receiver"); |
355 String receiver = atts.getValue("receiver"); |
336 if (receiver != null) { |
356 if (receiver != null) { |
337 site.setReceiver(type(receiver)); |
357 site.setReceiver(type(receiver)); |
338 site.setReceiver_count(Integer.parseInt(search(atts, "receiver_count"))); |
358 site.setReceiver_count(Integer.parseInt(search(atts, "receiver_count"))); |
339 } |
359 } |
340 scopes.peek().add(site); |
360 int methodHandle = Integer.parseInt(search(atts, "method_handle_intrinsic", "0")); |
|
361 if (lateInlining && scopes.size() == 0) { |
|
362 // The call was added before this round of late inlining |
|
363 } else if (methodHandle == 0) { |
|
364 scopes.peek().add(site); |
|
365 } else { |
|
366 // method handle call site can be followed by another |
|
367 // call (in case it is inlined). If that happens we |
|
368 // discard the method handle call site. So we keep |
|
369 // track of it but don't add it to the list yet. |
|
370 methodHandleSite = site; |
|
371 } |
341 } else if (qname.equals("regalloc")) { |
372 } else if (qname.equals("regalloc")) { |
342 compile.setAttempts(Integer.parseInt(search(atts, "attempts"))); |
373 compile.setAttempts(Integer.parseInt(search(atts, "attempts"))); |
343 } else if (qname.equals("inline_fail")) { |
374 } else if (qname.equals("inline_fail")) { |
344 scopes.peek().last().setReason(search(atts, "reason")); |
375 if (methodHandleSite != null) { |
|
376 scopes.peek().add(methodHandleSite); |
|
377 methodHandleSite = null; |
|
378 } |
|
379 if (lateInlining && scopes.size() == 0) { |
|
380 site.setReason(search(atts, "reason")); |
|
381 lateInlining = false; |
|
382 } else { |
|
383 scopes.peek().last().setReason(search(atts, "reason")); |
|
384 } |
|
385 } else if (qname.equals("inline_success")) { |
|
386 if (methodHandleSite != null) { |
|
387 throw new InternalError("method handle site should have been replaced"); |
|
388 } |
|
389 if (lateInlining && scopes.size() == 0) { |
|
390 site.setReason(null); |
|
391 } |
345 } else if (qname.equals("failure")) { |
392 } else if (qname.equals("failure")) { |
346 failureReason = search(atts, "reason"); |
393 failureReason = search(atts, "reason"); |
347 } else if (qname.equals("task_done")) { |
394 } else if (qname.equals("task_done")) { |
348 compile.setEnd(Double.parseDouble(search(atts, "stamp"))); |
395 compile.setEnd(Double.parseDouble(search(atts, "stamp"))); |
349 if (Integer.parseInt(search(atts, "success")) == 0) { |
396 if (Integer.parseInt(search(atts, "success")) == 0) { |
369 } else { |
416 } else { |
370 // uncommon trap inserted during parsing. |
417 // uncommon trap inserted during parsing. |
371 // ignore for now |
418 // ignore for now |
372 } |
419 } |
373 } else if (qname.equals("late_inline")) { |
420 } else if (qname.equals("late_inline")) { |
374 late_inline_scope = new Stack<CallSite>(); |
421 long inlineId = Long.parseLong(search(atts, "inline_id")); |
|
422 lateInlineScope = new Stack<CallSite>(); |
375 site = new CallSite(-999, method(search(atts, "method"))); |
423 site = new CallSite(-999, method(search(atts, "method"))); |
376 late_inline_scope.push(site); |
424 site.setInlineId(inlineId); |
|
425 lateInlineScope.push(site); |
377 } else if (qname.equals("jvms")) { |
426 } else if (qname.equals("jvms")) { |
378 // <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/> |
427 // <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/> |
379 if (currentTrap != null) { |
428 if (currentTrap != null) { |
380 currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci"))); |
429 currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci"))); |
381 } else if (late_inline_scope != null) { |
430 } else if (lateInlineScope != null) { |
382 bci = Integer.parseInt(search(atts, "bci")); |
431 bci = Integer.parseInt(search(atts, "bci")); |
383 site = new CallSite(bci, method(search(atts, "method"))); |
432 site = new CallSite(bci, method(search(atts, "method"))); |
384 late_inline_scope.push(site); |
433 lateInlineScope.push(site); |
385 } else { |
434 } else { |
386 // Ignore <eliminate_allocation type='667'>, |
435 // Ignore <eliminate_allocation type='667'>, |
387 // <eliminate_lock lock='1'>, |
436 // <eliminate_lock lock='1'>, |
388 // <replace_string_concat arguments='2' string_alloc='0' multiple='0'> |
437 // <replace_string_concat arguments='2' string_alloc='0' multiple='0'> |
389 } |
438 } |
|
439 } else if (qname.equals("inline_id")) { |
|
440 if (methodHandleSite != null) { |
|
441 throw new InternalError("method handle site should have been replaced"); |
|
442 } |
|
443 long id = Long.parseLong(search(atts, "id")); |
|
444 site.setInlineId(id); |
390 } else if (qname.equals("nmethod")) { |
445 } else if (qname.equals("nmethod")) { |
391 String id = makeId(atts); |
446 String id = makeId(atts); |
392 NMethod nm = new NMethod(Double.parseDouble(search(atts, "stamp")), |
447 NMethod nm = new NMethod(Double.parseDouble(search(atts, "stamp")), |
393 id, |
448 id, |
394 parseLong(atts.getValue("address")), |
449 parseLong(atts.getValue("address")), |
395 parseLong(atts.getValue("size"))); |
450 parseLong(atts.getValue("size"))); |
396 nmethods.put(id, nm); |
451 nmethods.put(id, nm); |
397 events.add(nm); |
452 events.add(nm); |
398 } else if (qname.equals("parse")) { |
453 } else if (qname.equals("parse")) { |
|
454 if (methodHandleSite != null) { |
|
455 throw new InternalError("method handle site should have been replaced"); |
|
456 } |
399 Method m = method(search(atts, "method")); |
457 Method m = method(search(atts, "method")); |
400 if (scopes.size() == 0) { |
458 if (lateInlining && scopes.size() == 0) { |
|
459 if (site.getMethod() != m) { |
|
460 System.out.println(site.getMethod()); |
|
461 System.out.println(m); |
|
462 throw new InternalError("Unexpected method mismatch during late inlining"); |
|
463 } |
|
464 } |
|
465 if (scopes.size() == 0 && !lateInlining) { |
401 compile.setMethod(m); |
466 compile.setMethod(m); |
402 scopes.push(site); |
467 scopes.push(site); |
403 } else { |
468 } else { |
404 if (site.getMethod() == m) { |
469 if (site.getMethod() == m) { |
405 scopes.push(site); |
470 scopes.push(site); |
425 String localName, |
490 String localName, |
426 String qname) { |
491 String qname) { |
427 if (qname.equals("parse")) { |
492 if (qname.equals("parse")) { |
428 indent -= 2; |
493 indent -= 2; |
429 scopes.pop(); |
494 scopes.pop(); |
|
495 if (scopes.size() == 0) { |
|
496 lateInlining = false; |
|
497 } |
430 } else if (qname.equals("uncommon_trap")) { |
498 } else if (qname.equals("uncommon_trap")) { |
431 currentTrap = null; |
499 currentTrap = null; |
432 } else if (qname.equals("late_inline")) { |
500 } else if (qname.equals("late_inline")) { |
433 // Populate late inlining info. |
501 // Populate late inlining info. |
434 |
502 if (scopes.size() != 0) { |
435 // late_inline scopes are specified in reverse order: |
503 throw new InternalError("scopes should be empty for late inline"); |
|
504 } |
|
505 // late inline scopes are specified in reverse order: |
436 // compiled method should be on top of stack. |
506 // compiled method should be on top of stack. |
437 CallSite caller = late_inline_scope.pop(); |
507 CallSite caller = lateInlineScope.pop(); |
438 Method m = compile.getMethod(); |
508 Method m = compile.getMethod(); |
439 if (m != caller.getMethod()) { |
509 if (m != caller.getMethod()) { |
440 System.out.println(m); |
510 System.out.println(m); |
441 System.out.println(caller.getMethod() + " bci: " + bci); |
511 System.out.println(caller.getMethod() + " bci: " + bci); |
442 throw new InternalError("call site and late_inline info don't match"); |
512 throw new InternalError("call site and late_inline info don't match"); |
443 } |
513 } |
444 |
514 |
445 // late_inline contains caller+bci info, convert it |
515 // late_inline contains caller+bci info, convert it |
446 // to bci+callee info used by LogCompilation. |
516 // to bci+callee info used by LogCompilation. |
447 site = compile.getLateInlineCall(); |
517 CallSite lateInlineSite = compile.getLateInlineCall(); |
|
518 ArrayDeque<CallSite> thisCallScopes = new ArrayDeque<CallSite>(); |
448 do { |
519 do { |
449 bci = caller.getBci(); |
520 bci = caller.getBci(); |
450 // Next inlined call. |
521 // Next inlined call. |
451 caller = late_inline_scope.pop(); |
522 caller = lateInlineScope.pop(); |
452 CallSite callee = new CallSite(bci, caller.getMethod()); |
523 CallSite callee = new CallSite(bci, caller.getMethod()); |
453 site.add(callee); |
524 callee.setInlineId(caller.getInlineId()); |
454 site = callee; |
525 thisCallScopes.addLast(callee); |
455 } while (!late_inline_scope.empty()); |
526 lateInlineSite.add(callee); |
|
527 lateInlineSite = callee; |
|
528 } while (!lateInlineScope.empty()); |
|
529 |
|
530 site = compile.getCall().findCallSite(thisCallScopes); |
|
531 if (site == null) { |
|
532 System.out.println(caller.getMethod() + " bci: " + bci); |
|
533 throw new InternalError("couldn't find call site"); |
|
534 } |
|
535 lateInlining = true; |
456 |
536 |
457 if (caller.getBci() != -999) { |
537 if (caller.getBci() != -999) { |
458 System.out.println(caller.getMethod()); |
538 System.out.println(caller.getMethod()); |
459 throw new InternalError("broken late_inline info"); |
539 throw new InternalError("broken late_inline info"); |
460 } |
540 } |
461 if (site.getMethod() != caller.getMethod()) { |
541 if (site.getMethod() != caller.getMethod()) { |
462 System.out.println(site.getMethod()); |
542 if (site.getInlineId() == caller.getInlineId()) { |
463 System.out.println(caller.getMethod()); |
543 site.setMethod(caller.getMethod()); |
464 throw new InternalError("call site and late_inline info don't match"); |
544 } else { |
|
545 System.out.println(site.getMethod()); |
|
546 System.out.println(caller.getMethod()); |
|
547 throw new InternalError("call site and late_inline info don't match"); |
|
548 } |
465 } |
549 } |
466 // late_inline is followed by parse with scopes.size() == 0, |
550 // late_inline is followed by parse with scopes.size() == 0, |
467 // 'site' will be pushed to scopes. |
551 // 'site' will be pushed to scopes. |
468 late_inline_scope = null; |
552 lateInlineScope = null; |
469 } else if (qname.equals("task")) { |
553 } else if (qname.equals("task")) { |
470 types.clear(); |
554 types.clear(); |
471 methods.clear(); |
555 methods.clear(); |
472 site = null; |
556 site = null; |
473 } |
557 } |