private void buildParseTagAnnotations()

in core/src/main/java/org/adoptopenjdk/jitwatch/model/bytecode/BytecodeAnnotationBuilder.java [494:748]


	private void buildParseTagAnnotations(Tag parseTag, BytecodeAnnotations annotations, IParseDictionary parseDictionary)
			throws AnnotationException
	{
		// Only interested in annotating the current method so
		// do not recurse into method or parse tags

		if (DEBUG_LOGGING)
		{
			logger.debug("Building parse tag annotations");
		}

		List<Tag> children = parseTag.getChildren();

		int currentBytecode = -1;

		Map<String, Map<String, String>> methodAttrs = new HashMap<>();
		Map<String, String> callAttrs = new HashMap<>();
		Map<String, String> lastMethodAttrs = new HashMap<>();

		String currentMethodID = parseTag.getAttributes().get(ATTR_METHOD);

		BytecodeInstruction currentInstruction = null;

		for (Tag child : children)
		{
			String name = child.getName();
			
			Map<String, String> tagAttrs = child.getAttributes();

			if (DEBUG_LOGGING_BYTECODE)
			{
				logger.debug("Examining child tag {}", child);
			}

			switch (name)
			{
			case TAG_BC:
			{
				String bciAttr = tagAttrs.get(ATTR_BCI);
				String codeAttr = tagAttrs.get(ATTR_CODE);

				currentBytecode = Integer.parseInt(bciAttr);
				int code = Integer.parseInt(codeAttr);
				callAttrs.clear();

				if (DEBUG_LOGGING_BYTECODE)
				{
					logger.debug("BC Tag {} {}", currentBytecode, code);
				}

				currentInstruction = getInstructionAtIndex(currentBytecode);

				if (DEBUG_LOGGING_BYTECODE)
				{
					logger.debug("Instruction at {} is {}", currentBytecode, currentInstruction);
				}

				break;
			}

			case TAG_CALL:
			{
				callAttrs.clear();
				callAttrs.putAll(tagAttrs);

				lastMethodAttrs.clear();
				String calleeId = tagAttrs.get("method");
				
				if (calleeId != null)
				{
					Map<String, String> calleeAttrs = methodAttrs.get(calleeId);
					
					if (calleeAttrs != null)
					{
						lastMethodAttrs.putAll(calleeAttrs);
					}
				}

				break;
			}

			case TAG_METHOD:
			{
				String methodId = tagAttrs.get("id");
				if (methodId != null)
				{
					methodAttrs.put(methodId, tagAttrs);
				}
				break;
			}

			case TAG_INLINE_SUCCESS:
			{
				if (!sanityCheckInline(currentInstruction))
				{
					throw new AnnotationException("Expected an invoke instruction (in INLINE_SUCCESS)", currentBytecode,
							currentInstruction);
				}

				String reason = tagAttrs.get(ATTR_REASON);
				String annotationText = buildInlineAnnotation(parseDictionary, lastMethodAttrs, callAttrs, reason, true);

				IMetaMember inlinedMember = ParseUtil.lookupMember(lastMethodAttrs.get(ATTR_ID), parseDictionary, model);

				LineAnnotation lineAnnotation = new LineAnnotation(annotationText, BCAnnotationType.INLINE_SUCCESS, inlinedMember);
								
				putAnnotation(currentMember, currentBytecode, lineAnnotation);

				break;
			}

			case TAG_INLINE_FAIL:
			{
				if (!sanityCheckInline(currentInstruction))
				{
					throw new AnnotationException("Expected an invoke instruction (in INLINE_FAIL)", currentBytecode,
							currentInstruction);
				}

				String reason = tagAttrs.get(ATTR_REASON);
				String annotationText = buildInlineAnnotation(parseDictionary, lastMethodAttrs, callAttrs, reason, false);
				
				IMetaMember inlinedMember = ParseUtil.lookupMember(lastMethodAttrs.get(ATTR_ID), parseDictionary, model);

				LineAnnotation lineAnnotation = new LineAnnotation(annotationText, BCAnnotationType.INLINE_FAIL, inlinedMember);
								
				putAnnotation(currentMember, currentBytecode, lineAnnotation);

				break;
			}

			case TAG_BRANCH:
			{
				if (!sanityCheckBranch(currentInstruction))
				{
					throw new AnnotationException("Expected a branch instruction (BRANCH)", currentBytecode, currentInstruction);
				}

				String branchAnnotation = buildBranchAnnotation(tagAttrs);

				putAnnotation(currentMember, currentBytecode, new LineAnnotation(branchAnnotation, BCAnnotationType.BRANCH));
				
				break;
			}

			case TAG_INTRINSIC:
			{
				if (!sanityCheckIntrinsic(currentInstruction))
				{
					throw new AnnotationException("Expected an invoke instruction (INTRINSIC)", currentBytecode,
							currentInstruction);
				}

				StringBuilder reason = new StringBuilder();
				reason.append("Intrinsic: ").append(tagAttrs.get(ATTR_ID));

				putAnnotation(currentMember, currentBytecode,
						new LineAnnotation(reason.toString(), BCAnnotationType.INTRINSIC_USED));

				break;
			}

			case TAG_UNCOMMON_TRAP:
			{
				String trapMethod = child.getAttributes().get(ATTR_METHOD);

				if (trapMethod == null || currentMethodID.equals(trapMethod))
				{
					visitTagUncommonTrap(child);
				}

				break;
			}

			case TAG_PHASE:
			{
				String phaseName = tagAttrs.get(ATTR_NAME);

				if (S_PARSE_HIR.equals(phaseName))
				{
					buildParseTagAnnotations(child, annotations, parseDictionary);
				}
				else
				{
					logger.warn("Don't know how to handle phase {}", phaseName);
				}

				break;
			}

			case TAG_VIRTUAL_CALL:
				putAnnotation(currentMember, currentBytecode,
						new LineAnnotation("Virtual call, not inlined", BCAnnotationType.VIRTUAL_CALL));
				break;

			case TAG_HOT_THROW:
			{

				MemberBytecode memberBytecode = currentMember.getMemberBytecode();

				if (memberBytecode != null)
				{
					ExceptionTable exceptionTable = memberBytecode.getExceptionTable();

					if (exceptionTable != null)
					{
						ExceptionTableEntry entry = exceptionTable.getEntryForBCI(currentBytecode);

						if (entry != null)
						{
							int exceptionBCI = entry.getTarget();

							String exceptionType = entry.getType();

							String preallocated = child.getAttributes().get(ATTR_PREALLOCATED);

							StringBuilder reason = new StringBuilder();

							reason.append(exceptionType.replaceAll(S_SLASH, S_DOT)).append(" thrown by this operation");

							BCAnnotationType annotationType;

							if (preallocated != null && "1".equals(preallocated))
							{
								reason.append(" has been pre-allocated.");
								annotationType = BCAnnotationType.HOT_THROW_PREALLOCATED;
							}
							else
							{
								reason.append(" was not pre-allocated.");
								annotationType = BCAnnotationType.HOT_THROW_NOT_PREALLOCATED;
							}

							putAnnotation(currentMember, exceptionBCI, new LineAnnotation(reason.toString(), annotationType));
						}
					}
					else
					{
						logger.warn("No ExceptionTable found for {}", currentMember);

					}
				}
				else
				{
					logger.warn("No MemberBytecode found for {}", currentMember);
				}
				break;
			}

			default:
				handleOther(child);
				break;
			}
		}
	}