mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -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[] substart;
|
||||
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.arraysPerRecord = arraysPerRecord;
|
||||
this.size = size;
|
||||
this.data = data;
|
||||
this.substart = substart;
|
||||
this.subdata = subdata;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return data.length / recordSize;
|
||||
return size;
|
||||
}
|
||||
|
||||
public int getRecordSize() {
|
||||
|
|
|
@ -22,6 +22,7 @@ package org.teavm.common;
|
|||
public class RecordArrayBuilder {
|
||||
private int recordSize;
|
||||
private int arraysPerRecord;
|
||||
private int size;
|
||||
private IntegerArray data = new IntegerArray(1);
|
||||
private IntegerArray substart = new IntegerArray(1);
|
||||
private IntegerArray subdata = new IntegerArray(1);
|
||||
|
@ -33,6 +34,9 @@ public class RecordArrayBuilder {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -45,11 +49,12 @@ public class RecordArrayBuilder {
|
|||
for (int i = 0; i < arraysPerRecord; ++i) {
|
||||
substart.add(-1);
|
||||
}
|
||||
++size;
|
||||
return new Record(offset, arrayOffset);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return data.size() / recordSize;
|
||||
return size;
|
||||
}
|
||||
|
||||
public int getRecordSize() {
|
||||
|
@ -71,7 +76,7 @@ public class RecordArrayBuilder {
|
|||
}
|
||||
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 {
|
||||
|
|
|
@ -18,6 +18,8 @@ package org.teavm.debugging;
|
|||
import java.io.*;
|
||||
import java.util.*;
|
||||
import org.teavm.common.IntegerArray;
|
||||
import org.teavm.common.RecordArray;
|
||||
import org.teavm.common.RecordArrayBuilder;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
|
@ -45,6 +47,7 @@ public class DebugInformation {
|
|||
Mapping lineMapping;
|
||||
Mapping callSiteMapping;
|
||||
MultiMapping[] variableMappings;
|
||||
RecordArray[] lineCallSites;
|
||||
CFG[] controlFlowGraphs;
|
||||
List<ClassMetadata> classesMetadata;
|
||||
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) {
|
||||
int keyIndex = indexByKey(mapping, location);
|
||||
int valueIndex = keyIndex >= 0 ? mapping.values[keyIndex] : -1;
|
||||
|
@ -283,6 +304,11 @@ public class DebugInformation {
|
|||
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) {
|
||||
int index = Collections.binarySearch(mapping.keyList(), location);
|
||||
return index >= 0 ? index : -index - 2;
|
||||
|
@ -307,6 +333,7 @@ public class DebugInformation {
|
|||
rebuildFileDescriptions();
|
||||
rebuildEntrances();
|
||||
rebuildMethodTree();
|
||||
rebuildLineCallSites();
|
||||
}
|
||||
|
||||
void rebuildMaps() {
|
||||
|
@ -439,6 +466,32 @@ public class DebugInformation {
|
|||
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 {
|
||||
int[] start;
|
||||
IntegerArray data;
|
||||
|
|
|
@ -98,18 +98,18 @@ public class Debugger {
|
|||
for (CallFrame frame : callStack) {
|
||||
boolean exits;
|
||||
String script = frame.originalLocation.getScript();
|
||||
GeneratedLocation genLoc = new GeneratedLocation(frame.originalLocation.getLine(),
|
||||
frame.originalLocation.getColumn());
|
||||
DebugInformation debugInfo = debugInformationMap.get(script);
|
||||
if (frame.getLocation() != null && debugInfo != null) {
|
||||
exits = false;
|
||||
MethodReference callMethod = debugInfo.getCallSite(genLoc);
|
||||
if (frame.getLocation() != null && frame.getLocation().getFileName() != null &&
|
||||
frame.getLocation().getLine() >= 0 && debugInfo != null) {
|
||||
MethodReference[] callMethods = debugInfo.getCallSites(frame.getLocation());
|
||||
exits = addFollowing(debugInfo, frame.getLocation(), script, new HashSet<SourceLocation>(),
|
||||
successors);
|
||||
if (enterMethod && callMethod != null) {
|
||||
for (MethodReference potentialMethod : debugInfo.getOverridingMethods(callMethod)) {
|
||||
for (GeneratedLocation loc : debugInfo.getMethodEntrances(potentialMethod)) {
|
||||
successors.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn()));
|
||||
if (enterMethod) {
|
||||
for (MethodReference callMethod : callMethods) {
|
||||
for (MethodReference potentialMethod : debugInfo.getOverridingMethods(callMethod)) {
|
||||
for (GeneratedLocation loc : debugInfo.getMethodEntrances(potentialMethod)) {
|
||||
successors.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user