868 |
868 |
869 /** |
869 /** |
870 * Records a custom infopoint in the code section. |
870 * Records a custom infopoint in the code section. |
871 * |
871 * |
872 * Compiler implementations can use this method to record non-standard infopoints, which are not |
872 * Compiler implementations can use this method to record non-standard infopoints, which are not |
873 * handled by the dedicated methods like {@link #recordCall}. |
873 * handled by dedicated methods like {@link #recordCall}. |
874 * |
874 * |
875 * @param infopoint the infopoint to record, usually a derived class from {@link Infopoint} |
875 * @param infopoint the infopoint to record, usually a derived class from {@link Infopoint} |
876 */ |
876 */ |
877 public void addInfopoint(Infopoint infopoint) { |
877 public void addInfopoint(Infopoint infopoint) { |
878 // The infopoints list must always be sorted |
|
879 if (!infopoints.isEmpty()) { |
|
880 Infopoint previousInfopoint = infopoints.get(infopoints.size() - 1); |
|
881 if (previousInfopoint.pcOffset > infopoint.pcOffset) { |
|
882 // This re-sorting should be very rare |
|
883 Collections.sort(infopoints); |
|
884 previousInfopoint = infopoints.get(infopoints.size() - 1); |
|
885 } |
|
886 if (previousInfopoint.pcOffset == infopoint.pcOffset) { |
|
887 if (infopoint.reason.canBeOmitted()) { |
|
888 return; |
|
889 } |
|
890 if (previousInfopoint.reason.canBeOmitted()) { |
|
891 Infopoint removed = infopoints.remove(infopoints.size() - 1); |
|
892 assert removed == previousInfopoint; |
|
893 } else { |
|
894 throw new RuntimeException("Infopoints that can not be omited should have distinct PCs"); |
|
895 } |
|
896 } |
|
897 } |
|
898 infopoints.add(infopoint); |
878 infopoints.add(infopoint); |
899 } |
879 } |
900 |
880 |
901 /** |
881 /** |
902 * Records an instruction mark within this method. |
882 * Records an instruction mark within this method. |