blob: b6e6c2eaf88c2e32d0f082f4a66ce52978e7c0f4 [file] [log] [blame]
// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.graph.DexDebugEvent.AdvancePC;
import com.android.tools.r8.graph.DexDebugEvent.Default;
import com.android.tools.r8.ir.code.Position;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import org.junit.Test;
public class DexDebugEventsTest {
static final DexItemFactory factory = new DexItemFactory();
static final DexMethod method = factory.createMethod(
factory.objectDescriptor,
factory.createString("foo"),
factory.voidDescriptor,
DexString.EMPTY_ARRAY);
@Test
public void testSpecialOpcodeRepresentation() {
{
// Smallest numeric opcode.
Default minDefault = new Default(0x0a);
assertEquals(0, minDefault.getPCDelta());
assertEquals(-4, minDefault.getLineDelta());
}
{
// Largest numeric opcode.
Default maxDefault = new Default(0xff);
assertEquals(16, maxDefault.getPCDelta());
assertEquals(1, maxDefault.getLineDelta());
}
{
// PC range of 16, smallest value for line is -4 delta.
Default maxPcDefault = new Default(0xff - 5);
assertEquals(16, maxPcDefault.getPCDelta());
assertEquals(-4, maxPcDefault.getLineDelta());
}
{
// Maximum line range is 15 points ranging from -4 to 10.
Default maxLineDefault = new Default(0x0a + 14);
assertEquals(0, maxLineDefault.getPCDelta());
assertEquals(10, maxLineDefault.getLineDelta());
}
// For a PC advance of 16, only the line range -4 to 1 can be represented.
for (int i = 0; i < 6; i++) {
Default maxPcAndRangeDefault = new Default(0xff - i);
assertEquals(16, maxPcAndRangeDefault.getPCDelta());
assertEquals(1 - i, maxPcAndRangeDefault.getLineDelta());
}
{
// For a line advance of 10 the max PC is 15.
Default maxPcIfUsingMaxLineDefault = new Default(0xff - 6);
assertEquals(15, maxPcIfUsingMaxLineDefault.getPCDelta());
assertEquals(10, maxPcIfUsingMaxLineDefault.getLineDelta());
}
}
@Test
public void testMaxPcMinLine() {
testAdvancement(0, 16, 5, 1, events -> {
assertEquals(1, events.size());
assertTrue(events.get(0) instanceof Default);
Default event = (Default) events.get(0);
assertEquals(16, event.getPCDelta());
assertEquals(-4, event.getLineDelta());
});
}
@Test
public void testMaxPcRemainingLine() {
testAdvancement(0, 16, 1, 2, events -> {
assertEquals(1, events.size());
assertTrue(events.get(0) instanceof Default);
Default event = (Default) events.get(0);
assertEquals(16, event.getPCDelta());
assertEquals(1, event.getLineDelta());
});
}
@Test
public void testMaxPcPlusOne() {
testAdvancement(0, 17, 1, 2, events -> {
assertEquals(2, events.size());
assertTrue(events.get(0) instanceof AdvancePC);
assertTrue(events.get(1) instanceof Default);
AdvancePC advancePC = (AdvancePC) events.get(0);
Default aDefault = (Default) events.get(1);
assertEquals(17, advancePC.delta + aDefault.getPCDelta());
assertEquals(1, aDefault.getLineDelta());
});
}
@Test
public void testMaxPcMaxLine() {
// If line delta is larger that 1 then there is not room for a pc delta of 16.
testAdvancement(0, 16, 1, 11, events -> {
assertEquals(2, events.size());
assertTrue(events.get(0) instanceof AdvancePC);
assertTrue(events.get(1) instanceof Default);
AdvancePC advancePC = (AdvancePC) events.get(0);
Default aDefault = (Default) events.get(1);
assertEquals(16, advancePC.delta + aDefault.getPCDelta());
assertEquals(10, aDefault.getLineDelta());
});
}
@Test
public void testMaxLineRemainingPc() {
testAdvancement(0, 15, 1, 11, events -> {
assertEquals(1, events.size());
assertTrue(events.get(0) instanceof Default);
Default event = (Default) events.get(0);
assertEquals(15, event.getPCDelta());
assertEquals(10, event.getLineDelta());
});
}
private void testAdvancement(
int pc, int nextPc, int line, int nextLine, Consumer<List<DexDebugEvent>> consumer) {
List<DexDebugEvent> events = new ArrayList<>();
DexDebugEventBuilder.emitAdvancementEvents(
pc,
new Position(line, null, method, null),
nextPc,
new Position(nextLine, null, method, null),
events,
factory);
consumer.accept(events);
}
}