mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 00:24:11 -08:00
Introduces another approach for setting temporary breakpoints at
methods' start lines when stepping in, due to bug in google chrome: http://code.google.com/p/chromium/issues/detail?id=407105
This commit is contained in:
parent
7cb3ce70c3
commit
7e1ff76c5d
|
@ -27,21 +27,26 @@ public class RecordArray {
|
||||||
private int[] data;
|
private int[] data;
|
||||||
private int[] substart;
|
private int[] substart;
|
||||||
private int[] subdata;
|
private int[] subdata;
|
||||||
|
private int size;
|
||||||
|
|
||||||
RecordArray(int recordSize, int arraysPerRecord, int[] data, int[] substart, int[] subdata) {
|
RecordArray(int recordSize, int arraysPerRecord, int size, int[] data, int[] substart, int[] subdata) {
|
||||||
this.recordSize = recordSize;
|
this.recordSize = recordSize;
|
||||||
this.arraysPerRecord = arraysPerRecord;
|
this.arraysPerRecord = arraysPerRecord;
|
||||||
|
this.size = size;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.substart = substart;
|
this.substart = substart;
|
||||||
this.subdata = subdata;
|
this.subdata = subdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Record get(int index) {
|
public Record get(int index) {
|
||||||
|
if (index < 0 || index >= size) {
|
||||||
|
throw new IndexOutOfBoundsException("Index " + index + " is outside of [0; " + size + ")");
|
||||||
|
}
|
||||||
return new Record(index * recordSize, index * arraysPerRecord);
|
return new Record(index * recordSize, index * arraysPerRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return data.length / recordSize;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRecordSize() {
|
public int getRecordSize() {
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.teavm.common;
|
||||||
public class RecordArrayBuilder {
|
public class RecordArrayBuilder {
|
||||||
private int recordSize;
|
private int recordSize;
|
||||||
private int arraysPerRecord;
|
private int arraysPerRecord;
|
||||||
|
private int size;
|
||||||
private IntegerArray data = new IntegerArray(1);
|
private IntegerArray data = new IntegerArray(1);
|
||||||
private IntegerArray substart = new IntegerArray(1);
|
private IntegerArray substart = new IntegerArray(1);
|
||||||
private IntegerArray subdata = new IntegerArray(1);
|
private IntegerArray subdata = new IntegerArray(1);
|
||||||
|
@ -33,6 +34,9 @@ public class RecordArrayBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Record get(int index) {
|
public Record get(int index) {
|
||||||
|
if (index < 0 || index >= size) {
|
||||||
|
throw new IndexOutOfBoundsException("Index " + index + " is outside of [0; " + size + ")");
|
||||||
|
}
|
||||||
return new Record(index * recordSize, index * arraysPerRecord);
|
return new Record(index * recordSize, index * arraysPerRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,11 +49,12 @@ public class RecordArrayBuilder {
|
||||||
for (int i = 0; i < arraysPerRecord; ++i) {
|
for (int i = 0; i < arraysPerRecord; ++i) {
|
||||||
substart.add(-1);
|
substart.add(-1);
|
||||||
}
|
}
|
||||||
|
++size;
|
||||||
return new Record(offset, arrayOffset);
|
return new Record(offset, arrayOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return data.size() / recordSize;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRecordSize() {
|
public int getRecordSize() {
|
||||||
|
@ -71,7 +76,7 @@ public class RecordArrayBuilder {
|
||||||
}
|
}
|
||||||
builtSubstart[i + 1] = builtSubdata.size();
|
builtSubstart[i + 1] = builtSubdata.size();
|
||||||
}
|
}
|
||||||
return new RecordArray(recordSize, arraysPerRecord, data.getAll(), builtSubstart, builtSubdata.getAll());
|
return new RecordArray(recordSize, arraysPerRecord, size, data.getAll(), builtSubstart, builtSubdata.getAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Record {
|
public class Record {
|
||||||
|
|
|
@ -18,6 +18,8 @@ package org.teavm.debugging;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.teavm.common.IntegerArray;
|
import org.teavm.common.IntegerArray;
|
||||||
|
import org.teavm.common.RecordArray;
|
||||||
|
import org.teavm.common.RecordArrayBuilder;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
@ -45,6 +47,7 @@ public class DebugInformation {
|
||||||
Mapping lineMapping;
|
Mapping lineMapping;
|
||||||
Mapping callSiteMapping;
|
Mapping callSiteMapping;
|
||||||
MultiMapping[] variableMappings;
|
MultiMapping[] variableMappings;
|
||||||
|
RecordArray[] lineCallSites;
|
||||||
CFG[] controlFlowGraphs;
|
CFG[] controlFlowGraphs;
|
||||||
List<ClassMetadata> classesMetadata;
|
List<ClassMetadata> classesMetadata;
|
||||||
MethodEntrances methodEntrances;
|
MethodEntrances methodEntrances;
|
||||||
|
@ -258,6 +261,24 @@ public class DebugInformation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MethodReference[] getCallSites(SourceLocation location) {
|
||||||
|
Integer fileIndex = fileNameMap.get(location.getFileName());
|
||||||
|
if (fileIndex == null) {
|
||||||
|
return new MethodReference[0];
|
||||||
|
}
|
||||||
|
RecordArray mapping = lineCallSites[fileIndex];
|
||||||
|
if (location.getLine() >= mapping.size()) {
|
||||||
|
return new MethodReference[0];
|
||||||
|
}
|
||||||
|
int[] callSiteIds = mapping.get(location.getLine()).getArray(0);
|
||||||
|
MethodReference[] methods = new MethodReference[callSiteIds.length];
|
||||||
|
for (int i = 0; i < callSiteIds.length; ++i) {
|
||||||
|
int exactMethodId = callSiteMapping.values[callSiteIds[i]];
|
||||||
|
methods[i] = getExactMethod(exactMethodId);
|
||||||
|
}
|
||||||
|
return methods;
|
||||||
|
}
|
||||||
|
|
||||||
private <T> T componentByKey(Mapping mapping, T[] values, GeneratedLocation location) {
|
private <T> T componentByKey(Mapping mapping, T[] values, GeneratedLocation location) {
|
||||||
int keyIndex = indexByKey(mapping, location);
|
int keyIndex = indexByKey(mapping, location);
|
||||||
int valueIndex = keyIndex >= 0 ? mapping.values[keyIndex] : -1;
|
int valueIndex = keyIndex >= 0 ? mapping.values[keyIndex] : -1;
|
||||||
|
@ -283,6 +304,11 @@ public class DebugInformation {
|
||||||
return index >= 0 ? index : -index - 2;
|
return index >= 0 ? index : -index - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int valueByKey(Mapping mapping, GeneratedLocation location) {
|
||||||
|
int index = indexByKey(mapping, location);
|
||||||
|
return index >= 0 ? mapping.values[index] : -1;
|
||||||
|
}
|
||||||
|
|
||||||
private int indexByKey(MultiMapping mapping, GeneratedLocation location) {
|
private int indexByKey(MultiMapping mapping, GeneratedLocation location) {
|
||||||
int index = Collections.binarySearch(mapping.keyList(), location);
|
int index = Collections.binarySearch(mapping.keyList(), location);
|
||||||
return index >= 0 ? index : -index - 2;
|
return index >= 0 ? index : -index - 2;
|
||||||
|
@ -307,6 +333,7 @@ public class DebugInformation {
|
||||||
rebuildFileDescriptions();
|
rebuildFileDescriptions();
|
||||||
rebuildEntrances();
|
rebuildEntrances();
|
||||||
rebuildMethodTree();
|
rebuildMethodTree();
|
||||||
|
rebuildLineCallSites();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rebuildMaps() {
|
void rebuildMaps() {
|
||||||
|
@ -439,6 +466,32 @@ public class DebugInformation {
|
||||||
return exactMethodMap.get(entry);
|
return exactMethodMap.get(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void rebuildLineCallSites() {
|
||||||
|
lineCallSites = new RecordArray[fileNames.length];
|
||||||
|
RecordArrayBuilder[] builders = new RecordArrayBuilder[fileNames.length];
|
||||||
|
for (int i = 0; i < lineCallSites.length; ++i) {
|
||||||
|
builders[i] = new RecordArrayBuilder(0, 1);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < callSiteMapping.lines.length; ++i) {
|
||||||
|
GeneratedLocation loc = callSiteMapping.key(i);
|
||||||
|
int methodId = callSiteMapping.values[i];
|
||||||
|
if (methodId >= 0) {
|
||||||
|
int line = valueByKey(lineMapping, loc);
|
||||||
|
int fileId = valueByKey(fileMapping, loc);
|
||||||
|
if (fileId >= 0 && line >= 0) {
|
||||||
|
RecordArrayBuilder builder = builders[fileId];
|
||||||
|
while (builder.size() <= line) {
|
||||||
|
builder.add();
|
||||||
|
}
|
||||||
|
builder.get(line).getArray(0).add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < lineCallSites.length; ++i) {
|
||||||
|
lineCallSites[i] = builders[i].build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MethodEntrancesBuilder {
|
class MethodEntrancesBuilder {
|
||||||
int[] start;
|
int[] start;
|
||||||
IntegerArray data;
|
IntegerArray data;
|
||||||
|
|
|
@ -98,21 +98,21 @@ public class Debugger {
|
||||||
for (CallFrame frame : callStack) {
|
for (CallFrame frame : callStack) {
|
||||||
boolean exits;
|
boolean exits;
|
||||||
String script = frame.originalLocation.getScript();
|
String script = frame.originalLocation.getScript();
|
||||||
GeneratedLocation genLoc = new GeneratedLocation(frame.originalLocation.getLine(),
|
|
||||||
frame.originalLocation.getColumn());
|
|
||||||
DebugInformation debugInfo = debugInformationMap.get(script);
|
DebugInformation debugInfo = debugInformationMap.get(script);
|
||||||
if (frame.getLocation() != null && debugInfo != null) {
|
if (frame.getLocation() != null && frame.getLocation().getFileName() != null &&
|
||||||
exits = false;
|
frame.getLocation().getLine() >= 0 && debugInfo != null) {
|
||||||
MethodReference callMethod = debugInfo.getCallSite(genLoc);
|
MethodReference[] callMethods = debugInfo.getCallSites(frame.getLocation());
|
||||||
exits = addFollowing(debugInfo, frame.getLocation(), script, new HashSet<SourceLocation>(),
|
exits = addFollowing(debugInfo, frame.getLocation(), script, new HashSet<SourceLocation>(),
|
||||||
successors);
|
successors);
|
||||||
if (enterMethod && callMethod != null) {
|
if (enterMethod) {
|
||||||
|
for (MethodReference callMethod : callMethods) {
|
||||||
for (MethodReference potentialMethod : debugInfo.getOverridingMethods(callMethod)) {
|
for (MethodReference potentialMethod : debugInfo.getOverridingMethods(callMethod)) {
|
||||||
for (GeneratedLocation loc : debugInfo.getMethodEntrances(potentialMethod)) {
|
for (GeneratedLocation loc : debugInfo.getMethodEntrances(potentialMethod)) {
|
||||||
successors.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn()));
|
successors.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
exits = true;
|
exits = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user