7
7
import static com .datadog .debugger .instrumentation .ASMHelper .invokeVirtual ;
8
8
import static com .datadog .debugger .instrumentation .ASMHelper .isFinalField ;
9
9
import static com .datadog .debugger .instrumentation .ASMHelper .isStaticField ;
10
+ import static com .datadog .debugger .instrumentation .ASMHelper .isStore ;
10
11
import static com .datadog .debugger .instrumentation .ASMHelper .ldc ;
11
12
import static com .datadog .debugger .instrumentation .ASMHelper .newInstance ;
12
13
import static com .datadog .debugger .instrumentation .Types .CAPTURED_CONTEXT_TYPE ;
68
69
import org .slf4j .LoggerFactory ;
69
70
70
71
public class CapturedContextInstrumentor extends Instrumentor {
71
- private static final Logger log = LoggerFactory .getLogger (CapturedContextInstrumentor .class );
72
+ private static final Logger LOGGER = LoggerFactory .getLogger (CapturedContextInstrumentor .class );
72
73
private final boolean captureSnapshot ;
73
74
private final Limits limits ;
74
75
private final LabelNode contextInitLabel = new LabelNode ();
@@ -639,8 +640,8 @@ private void rewriteLocalVarInsn(LocalVariableNode localVar, int oldSlot, int ne
639
640
// 10: astore_1
640
641
// 11: aload_1
641
642
// range for slot 1 starts at 11
642
- // javac always starts the range right after the init of the local var, so we can just look for
643
- // the previous instruction
643
+ // javac often starts the range right after the init of the local var, so we can just look for
644
+ // the previous instruction. But not always, and we put an arbitrary limit to 10 instructions
644
645
// for kotlinc, many instructions can separate the init and the range start
645
646
// ex:
646
647
// LocalVariableTable:
@@ -656,18 +657,26 @@ private void rewriteLocalVarInsn(LocalVariableNode localVar, int oldSlot, int ne
656
657
private static void rewritePreviousStoreInsn (
657
658
LocalVariableNode localVar , int oldSlot , int newSlot ) {
658
659
AbstractInsnNode previous = localVar .start .getPrevious ();
659
- while (previous != null
660
- && (!(previous instanceof VarInsnNode ) || ((VarInsnNode ) previous ).var != oldSlot )) {
660
+ int processed = 0 ;
661
+ // arbitrary fixing limit to 10 previous instructions to look at
662
+ while (previous != null && !isVarStoreForSlot (previous , oldSlot ) && processed < 10 ) {
661
663
previous = previous .getPrevious ();
664
+ processed ++;
662
665
}
663
- if (previous != null ) {
666
+ if (isVarStoreForSlot ( previous , oldSlot ) ) {
664
667
VarInsnNode varInsnNode = (VarInsnNode ) previous ;
665
668
if (varInsnNode .var == oldSlot ) {
666
669
varInsnNode .var = newSlot ;
667
670
}
668
671
}
669
672
}
670
673
674
+ private static boolean isVarStoreForSlot (AbstractInsnNode node , int slotIdx ) {
675
+ return node instanceof VarInsnNode
676
+ && isStore (node .getOpcode ())
677
+ && ((VarInsnNode ) node ).var == slotIdx ;
678
+ }
679
+
671
680
private void createInProbeFinallyHandler (LabelNode inProbeStartLabel , LabelNode inProbeEndLabel ) {
672
681
LabelNode handlerLabel = new LabelNode ();
673
682
InsnList handler = new InsnList ();
@@ -1234,7 +1243,7 @@ private static void addInheritedStaticFields(
1234
1243
FieldNode fieldNode =
1235
1244
new FieldNode (field .getModifiers (), field .getName (), desc , null , field );
1236
1245
results .add (fieldNode );
1237
- log .debug ("Adding static inherited field {}" , fieldNode .name );
1246
+ LOGGER .debug ("Adding static inherited field {}" , fieldNode .name );
1238
1247
fieldCount ++;
1239
1248
if (fieldCount > limits .maxFieldCount ) {
1240
1249
return ;
0 commit comments