@Nonnull public Label newSwitchPayloadReferenceLabel(@Nonnull MethodLocation switchLocation, @Nonnull int[] codeAddressToIndex, int codeAddress) { MethodLocation referent = instructionList.get(mapCodeAddressToIndex(codeAddressToIndex, codeAddress)); SwitchPayloadReferenceLabel label = new SwitchPayloadReferenceLabel(); label.switchLocation = switchLocation; referent.getLabels().add(label); return label; }
@Nullable private MethodLocation findSwitchForPayload(@Nonnull MethodLocation payloadLocation) { MethodLocation location = payloadLocation; MethodLocation switchLocation = null; do { for (Label label : location.getLabels()) { if (label instanceof SwitchPayloadReferenceLabel) { if (switchLocation != null) { throw new IllegalStateException("Multiple switch instructions refer to the same payload. " + "This is not currently supported. Please file a bug :)"); } switchLocation = ((SwitchPayloadReferenceLabel) label).switchLocation; } } // A switch instruction can refer to the payload instruction itself, or to a nop before the payload // instruction. // We need to search for all occurrences of a switch reference, so we can detect when multiple switch // statements refer to the same payload // TODO: confirm that it could refer to the first NOP in a series of NOPs preceding the payload if (location.index == 0) { return switchLocation; } location = instructionList.get(location.index - 1); if (location.instruction == null || location.instruction.getOpcode() != Opcode.NOP) { return switchLocation; } } while (true); }
@Test public void replacingInstructionGetsLabelsAtInsertionAddress() { manipulator = OptimizerTester.getGraphManipulator(CLASS_NAME, "hasLabelOnConstantizableOp(I)I"); BuilderInstruction addition = new BuilderInstruction11n(Opcode.CONST_4, 0, 2); assertEquals(1, manipulator.getInstruction(3).getLocation().getLabels().size()); manipulator.replaceInstruction(3, addition); assertEquals(1, manipulator.getInstruction(3).getLocation().getLabels().size()); }
@Nonnull public Label addNewLabel() { Label newLabel = new Label(); getLabels().add(newLabel); return newLabel; }
@Nonnull public Label addNewLabel() { Label newLabel = new Label(); getLabels().add(newLabel); return newLabel; }
@Nonnull public Label addNewLabel() { Label label = new Label(this); getLabels(true).add(label); return label; }
@Nonnull public Label newSwitchPayloadReferenceLabel(@Nonnull MethodLocation switchLocation, @Nonnull int[] codeAddressToIndex, int codeAddress) { MethodLocation referent = instructionList.get(mapCodeAddressToIndex(codeAddressToIndex, codeAddress)); SwitchPayloadReferenceLabel label = new SwitchPayloadReferenceLabel(); label.switchLocation = switchLocation; referent.getLabels().add(label); return label; }
@Nonnull public Label newSwitchPayloadReferenceLabel(@Nonnull MethodLocation switchLocation, @Nonnull int[] codeAddressToIndex, int codeAddress) { MethodLocation referent = instructionList.get(mapCodeAddressToIndex(codeAddressToIndex, codeAddress)); SwitchPayloadReferenceLabel label = new SwitchPayloadReferenceLabel(); label.switchLocation = switchLocation; referent.getLabels().add(label); return label; }
@Nonnull public Label newSwitchPayloadReferenceLabel(@Nonnull MethodLocation switchLocation, @Nonnull int[] codeAddressToIndex, int codeAddress) { MethodLocation referent = instructionList.get(mapCodeAddressToIndex(codeAddressToIndex, codeAddress)); SwitchPayloadReferenceLabel label = new SwitchPayloadReferenceLabel(); label.switchLocation = switchLocation; referent.getLabels().add(label); return label; }
@Nonnull public Label newSwitchPayloadReferenceLabel(@Nonnull MethodLocation switchLocation, @Nonnull int[] codeAddressToIndex, int codeAddress) { MethodLocation referent = instructionList.get(mapCodeAddressToIndex(codeAddressToIndex, codeAddress)); SwitchPayloadReferenceLabel label = new SwitchPayloadReferenceLabel(); label.switchLocation = switchLocation; referent.getLabels().add(label); return label; }
void mergeInto(@Nonnull MethodLocation other) { if (this.labels != null || other.labels != null) { List<Label> otherLabels = other.getLabels(true); for (Label label: this.getLabels(false)) { label.location = other; otherLabels.add(label); } this.labels = null; } if (this.debugItems != null || other.labels != null) { // We need to keep the debug items in the same order. We add the other debug items to this list, then reassign // the list. List<BuilderDebugItem> debugItems = getDebugItems(true); for (BuilderDebugItem debugItem: debugItems) { debugItem.location = other; } debugItems.addAll(other.getDebugItems(false)); other.debugItems = debugItems; this.debugItems = null; } }
@Nullable private MethodLocation findSwitchForPayload(@Nonnull MethodLocation payloadLocation) { MethodLocation location = payloadLocation; MethodLocation switchLocation = null; do { for (Label label: location.getLabels()) { if (label instanceof SwitchPayloadReferenceLabel) { if (switchLocation != null) { throw new IllegalStateException("Multiple switch instructions refer to the same payload. " + "This is not currently supported. Please file a bug :)"); } switchLocation = ((SwitchPayloadReferenceLabel)label).switchLocation; } } // A switch instruction can refer to the payload instruction itself, or to a nop before the payload // instruction. // We need to search for all occurrences of a switch reference, so we can detect when multiple switch // statements refer to the same payload // TODO: confirm that it could refer to the first NOP in a series of NOPs preceding the payload if (location.index == 0) { return switchLocation; } location = instructionList.get(location.index - 1); if (location.instruction == null || location.instruction.getOpcode() != Opcode.NOP) { return switchLocation; } } while (true); }
@Nullable private MethodLocation findSwitchForPayload(@Nonnull MethodLocation payloadLocation) { MethodLocation location = payloadLocation; MethodLocation switchLocation = null; do { for (Label label : location.getLabels()) { if (label instanceof SwitchPayloadReferenceLabel) { if (switchLocation != null) { throw new IllegalStateException("Multiple switch instructions refer to the same payload. " + "This is not currently supported. Please file a bug :)"); } switchLocation = ((SwitchPayloadReferenceLabel) label).switchLocation; } } // A switch instruction can refer to the payload instruction itself, or to a nop before the payload // instruction. // We need to search for all occurrences of a switch reference, so we can detect when multiple switch // statements refer to the same payload // TODO: confirm that it could refer to the first NOP in a series of NOPs preceding the payload if (location.index == 0) { return switchLocation; } location = instructionList.get(location.index - 1); if (location.instruction == null || location.instruction.getOpcode() != Opcode.NOP) { return switchLocation; } } while (true); }
@Nullable private MethodLocation findSwitchForPayload(@Nonnull MethodLocation payloadLocation) { MethodLocation location = payloadLocation; MethodLocation switchLocation = null; do { for (Label label: location.getLabels()) { if (label instanceof SwitchPayloadReferenceLabel) { if (switchLocation != null) { throw new IllegalStateException("Multiple switch instructions refer to the same payload. " + "This is not currently supported. Please file a bug :)"); } switchLocation = ((SwitchPayloadReferenceLabel)label).switchLocation; } } // A switch instruction can refer to the payload instruction itself, or to a nop before the payload // instruction. // We need to search for all occurrences of a switch reference, so we can detect when multiple switch // statements refer to the same payload // TODO: confirm that it could refer to the first NOP in a series of NOPs preceding the payload if (location.index == 0) { return switchLocation; } location = instructionList.get(location.index - 1); if (location.instruction == null || location.instruction.getOpcode() != Opcode.NOP) { return switchLocation; } } while (true); }
/** * Adds a new named label at the current location. * * Any previous unplaced references to a label of this name will now refer to this label/location * * @param name The name of the label to add * @return A LabelRef representing the label */ @Nonnull public Label addLabel(@Nonnull String name) { Label label = labels.get(name); if (label != null) { if (label.isPlaced()) { throw new IllegalArgumentException("There is already a label with that name."); } else { currentLocation.getLabels().add(label); } } else { label = currentLocation.addNewLabel(); labels.put(name, label); } return label; }
@Nullable private MethodLocation findSwitchForPayload(@Nonnull MethodLocation payloadLocation) { MethodLocation location = payloadLocation; MethodLocation switchLocation = null; do { for (Label label: location.getLabels()) { if (label instanceof SwitchPayloadReferenceLabel) { if (switchLocation != null) { throw new IllegalStateException("Multiple switch instructions refer to the same payload. " + "This is not currently supported. Please file a bug :)"); } switchLocation = ((SwitchPayloadReferenceLabel)label).switchLocation; } } // A switch instruction can refer to the payload instruction itself, or to a nop before the payload // instruction. // We need to search for all occurrences of a switch reference, so we can detect when multiple switch // statements refer to the same payload // TODO: confirm that it could refer to the first NOP in a series of NOPs preceding the payload if (location.index == 0) { return switchLocation; } location = instructionList.get(location.index - 1); if (location.instruction == null || location.instruction.getOpcode() != Opcode.NOP) { return switchLocation; } } while (true); }
/** * Adds a new named label at the current location. * * Any previous unplaced references to a label of this name will now refer to this label/location * * @param name The name of the label to add * @return A LabelRef representing the label */ @Nonnull public Label addLabel(@Nonnull String name) { Label label = labels.get(name); if (label != null) { if (label.isPlaced()) { throw new IllegalArgumentException("There is already a label with that name."); } else { currentLocation.getLabels().add(label); } } else { label = currentLocation.addNewLabel(); labels.put(name, label); } return label; }
/** * Adds a new named label at the current location. * * Any previous unplaced references to a label of this name will now refer to this label/location * * @param name The name of the label to add * @return A LabelRef representing the label */ @Nonnull public Label addLabel(@Nonnull String name) { Label label = labels.get(name); if (label != null) { if (label.isPlaced()) { throw new IllegalArgumentException("There is already a label with that name."); } else { currentLocation.getLabels().add(label); } } else { label = currentLocation.addNewLabel(); labels.put(name, label); } return label; }