mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-09 08:24:10 -08:00
Adds reordering of call sites to achieve natural stepping in call
hierarchy.
This commit is contained in:
parent
0f81841cf5
commit
3bc8887e4f
|
@ -178,6 +178,24 @@ public class DebugInformation {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GeneratedLocation getNearestCallSite(GeneratedLocation location) {
|
||||||
|
int keyIndex = indexByKey(callSiteMapping, location);
|
||||||
|
if (keyIndex < 0) {
|
||||||
|
keyIndex = 0;
|
||||||
|
}
|
||||||
|
while (keyIndex < callSiteMapping.values.length) {
|
||||||
|
int valueIndex = callSiteMapping.values[keyIndex];
|
||||||
|
if (valueIndex >= 0) {
|
||||||
|
MethodReference method = getExactMethod(valueIndex);
|
||||||
|
if (method != null) {
|
||||||
|
return new GeneratedLocation(callSiteMapping.lines[keyIndex], callSiteMapping.columns[keyIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++keyIndex;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public MethodReference getCallSite(GeneratedLocation location) {
|
public MethodReference getCallSite(GeneratedLocation location) {
|
||||||
int keyIndex = indexByKey(callSiteMapping, location);
|
int keyIndex = indexByKey(callSiteMapping, location);
|
||||||
if (keyIndex < 0) {
|
if (keyIndex < 0) {
|
||||||
|
|
|
@ -117,8 +117,10 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void emitCallSite(MethodReference method) {
|
public DeferredCallSite emitCallSite() {
|
||||||
if (method != null) {
|
DeferredCallSite callSite = new DeferredCallSite() {
|
||||||
|
int index = callSiteMapping.values.size();
|
||||||
|
@Override public void setMethod(MethodReference method) {
|
||||||
int methodIndex = methods.index(method.getDescriptor().toString());
|
int methodIndex = methods.index(method.getDescriptor().toString());
|
||||||
int classIndex = classes.index(method.getClassName());
|
int classIndex = classes.index(method.getClassName());
|
||||||
long fullIndex = ((long)classIndex << 32) | methodIndex;
|
long fullIndex = ((long)classIndex << 32) | methodIndex;
|
||||||
|
@ -128,10 +130,16 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
|
||||||
exactMethodMap.put(fullIndex, exactMethodIndex);
|
exactMethodMap.put(fullIndex, exactMethodIndex);
|
||||||
exactMethods.add(fullIndex);
|
exactMethods.add(fullIndex);
|
||||||
}
|
}
|
||||||
callSiteMapping.add(locationProvider, exactMethodIndex);
|
callSiteMapping.values.set(index, exactMethodIndex);
|
||||||
} else {
|
|
||||||
callSiteMapping.add(locationProvider, -1);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
callSiteMapping.add(locationProvider, -1);
|
||||||
|
return callSite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void emitEmptyCallSite() {
|
||||||
|
callSiteMapping.add(locationProvider, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -17,7 +17,6 @@ package org.teavm.debugging;
|
||||||
|
|
||||||
import org.teavm.codegen.LocationProvider;
|
import org.teavm.codegen.LocationProvider;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodReference;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -34,7 +33,9 @@ public interface DebugInformationEmitter {
|
||||||
|
|
||||||
void emitVariable(String[] sourceNames, String generatedName);
|
void emitVariable(String[] sourceNames, String generatedName);
|
||||||
|
|
||||||
void emitCallSite(MethodReference method);
|
DeferredCallSite emitCallSite();
|
||||||
|
|
||||||
|
void emitEmptyCallSite();
|
||||||
|
|
||||||
void addClass(String className, String parentName);
|
void addClass(String className, String parentName);
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,13 @@ public class Debugger {
|
||||||
DebugInformation mainDebugInfo = debugInformationMap.get(frame.originalLocation.getScript());
|
DebugInformation mainDebugInfo = debugInformationMap.get(frame.originalLocation.getScript());
|
||||||
GeneratedLocation genLoc = new GeneratedLocation(frame.originalLocation.getLine(),
|
GeneratedLocation genLoc = new GeneratedLocation(frame.originalLocation.getLine(),
|
||||||
frame.originalLocation.getColumn());
|
frame.originalLocation.getColumn());
|
||||||
MethodReference callMethod = mainDebugInfo != null ? mainDebugInfo.getCallSite(genLoc) : null;
|
MethodReference callMethod = null;
|
||||||
|
if (mainDebugInfo != null) {
|
||||||
|
GeneratedLocation callSiteLoc = mainDebugInfo.getNearestCallSite(genLoc);
|
||||||
|
if (callSiteLoc != null) {
|
||||||
|
callMethod = mainDebugInfo.getCallSite(callSiteLoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
String script = frame.originalLocation.getScript();
|
String script = frame.originalLocation.getScript();
|
||||||
DebugInformation debugInfo = debugInformationMap.get(script);
|
DebugInformation debugInfo = debugInformationMap.get(script);
|
||||||
if (debugInfo != null) {
|
if (debugInfo != null) {
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.debugging;
|
||||||
|
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public interface DeferredCallSite {
|
||||||
|
void setMethod(MethodReference method);
|
||||||
|
}
|
|
@ -42,7 +42,15 @@ public class DummyDebugInformationEmitter implements DebugInformationEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void emitCallSite(MethodReference method) {
|
public DeferredCallSite emitCallSite() {
|
||||||
|
return new DeferredCallSite() {
|
||||||
|
@Override public void setMethod(MethodReference method) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void emitEmptyCallSite() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.teavm.codegen.NamingStrategy;
|
||||||
import org.teavm.codegen.SourceWriter;
|
import org.teavm.codegen.SourceWriter;
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
import org.teavm.debugging.DebugInformationEmitter;
|
import org.teavm.debugging.DebugInformationEmitter;
|
||||||
|
import org.teavm.debugging.DeferredCallSite;
|
||||||
import org.teavm.debugging.DummyDebugInformationEmitter;
|
import org.teavm.debugging.DummyDebugInformationEmitter;
|
||||||
import org.teavm.javascript.ast.*;
|
import org.teavm.javascript.ast.*;
|
||||||
import org.teavm.javascript.ni.GeneratorContext;
|
import org.teavm.javascript.ni.GeneratorContext;
|
||||||
|
@ -50,7 +51,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
private ServiceRepository services;
|
private ServiceRepository services;
|
||||||
private DebugInformationEmitter debugEmitter = new DummyDebugInformationEmitter();
|
private DebugInformationEmitter debugEmitter = new DummyDebugInformationEmitter();
|
||||||
private Deque<NodeLocation> locationStack = new ArrayDeque<>();
|
private Deque<NodeLocation> locationStack = new ArrayDeque<>();
|
||||||
private Deque<MethodReference> callSiteStack = new ArrayDeque<>();
|
private DeferredCallSite lastCallSite;
|
||||||
|
|
||||||
private static class InjectorHolder {
|
private static class InjectorHolder {
|
||||||
public final Injector injector;
|
public final Injector injector;
|
||||||
|
@ -594,17 +595,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pushCallSite(MethodReference method) {
|
|
||||||
callSiteStack.push(method);
|
|
||||||
debugEmitter.emitCallSite(method);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void popCallSite() {
|
|
||||||
callSiteStack.pop();
|
|
||||||
MethodReference method = callSiteStack.peek();
|
|
||||||
debugEmitter.emitCallSite(method);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignmentStatement statement) throws RenderingException {
|
public void visit(AssignmentStatement statement) throws RenderingException {
|
||||||
try {
|
try {
|
||||||
|
@ -1296,7 +1286,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
if (expr.getLocation() != null) {
|
if (expr.getLocation() != null) {
|
||||||
pushLocation(expr.getLocation());
|
pushLocation(expr.getLocation());
|
||||||
}
|
}
|
||||||
pushCallSite(expr.getMethod());
|
|
||||||
Injector injector = getInjector(expr.getMethod());
|
Injector injector = getInjector(expr.getMethod());
|
||||||
if (injector != null) {
|
if (injector != null) {
|
||||||
injector.generate(new InjectorContextImpl(expr.getArguments()), expr.getMethod());
|
injector.generate(new InjectorContextImpl(expr.getArguments()), expr.getMethod());
|
||||||
|
@ -1304,9 +1293,16 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
String className = naming.getNameFor(expr.getMethod().getClassName());
|
String className = naming.getNameFor(expr.getMethod().getClassName());
|
||||||
String name = naming.getNameFor(expr.getMethod());
|
String name = naming.getNameFor(expr.getMethod());
|
||||||
String fullName = naming.getFullNameFor(expr.getMethod());
|
String fullName = naming.getFullNameFor(expr.getMethod());
|
||||||
|
DeferredCallSite callSite = null;
|
||||||
|
boolean shouldEraseCallSite = lastCallSite == null;
|
||||||
switch (expr.getType()) {
|
switch (expr.getType()) {
|
||||||
case STATIC:
|
case STATIC:
|
||||||
|
callSite = debugEmitter.emitCallSite();
|
||||||
|
if (lastCallSite == null) {
|
||||||
|
lastCallSite = callSite;
|
||||||
|
}
|
||||||
writer.append(fullName).append("(");
|
writer.append(fullName).append("(");
|
||||||
|
debugEmitter.emitEmptyCallSite();
|
||||||
for (int i = 0; i < expr.getArguments().size(); ++i) {
|
for (int i = 0; i < expr.getArguments().size(); ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
writer.append(",").ws();
|
writer.append(",").ws();
|
||||||
|
@ -1316,7 +1312,12 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
writer.append(')');
|
writer.append(')');
|
||||||
break;
|
break;
|
||||||
case SPECIAL:
|
case SPECIAL:
|
||||||
|
callSite = debugEmitter.emitCallSite();
|
||||||
|
if (lastCallSite == null) {
|
||||||
|
lastCallSite = callSite;
|
||||||
|
}
|
||||||
writer.append(fullName).append("(");
|
writer.append(fullName).append("(");
|
||||||
|
debugEmitter.emitEmptyCallSite();
|
||||||
expr.getArguments().get(0).acceptVisitor(this);
|
expr.getArguments().get(0).acceptVisitor(this);
|
||||||
for (int i = 1; i < expr.getArguments().size(); ++i) {
|
for (int i = 1; i < expr.getArguments().size(); ++i) {
|
||||||
writer.append(",").ws();
|
writer.append(",").ws();
|
||||||
|
@ -1326,7 +1327,12 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
break;
|
break;
|
||||||
case DYNAMIC:
|
case DYNAMIC:
|
||||||
expr.getArguments().get(0).acceptVisitor(this);
|
expr.getArguments().get(0).acceptVisitor(this);
|
||||||
|
callSite = debugEmitter.emitCallSite();
|
||||||
|
if (lastCallSite == null) {
|
||||||
|
lastCallSite = callSite;
|
||||||
|
}
|
||||||
writer.append(".").append(name).append("(");
|
writer.append(".").append(name).append("(");
|
||||||
|
debugEmitter.emitEmptyCallSite();
|
||||||
for (int i = 1; i < expr.getArguments().size(); ++i) {
|
for (int i = 1; i < expr.getArguments().size(); ++i) {
|
||||||
if (i > 1) {
|
if (i > 1) {
|
||||||
writer.append(",").ws();
|
writer.append(",").ws();
|
||||||
|
@ -1336,7 +1342,12 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
writer.append(')');
|
writer.append(')');
|
||||||
break;
|
break;
|
||||||
case CONSTRUCTOR:
|
case CONSTRUCTOR:
|
||||||
|
callSite = debugEmitter.emitCallSite();
|
||||||
|
if (lastCallSite == null) {
|
||||||
|
lastCallSite = callSite;
|
||||||
|
}
|
||||||
writer.append(className).append(".").append(name).append("(");
|
writer.append(className).append(".").append(name).append("(");
|
||||||
|
debugEmitter.emitEmptyCallSite();
|
||||||
for (int i = 0; i < expr.getArguments().size(); ++i) {
|
for (int i = 0; i < expr.getArguments().size(); ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
writer.append(",").ws();
|
writer.append(",").ws();
|
||||||
|
@ -1346,8 +1357,14 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
writer.append(')');
|
writer.append(')');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (lastCallSite != null) {
|
||||||
|
lastCallSite.setMethod(expr.getMethod());
|
||||||
|
lastCallSite = callSite;
|
||||||
|
}
|
||||||
|
if (shouldEraseCallSite) {
|
||||||
|
lastCallSite = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
popCallSite();
|
|
||||||
if (expr.getLocation() != null) {
|
if (expr.getLocation() != null) {
|
||||||
popLocation();
|
popLocation();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user