11package datadog .trace .instrumentation .jetty9 ;
22
3- import static java .lang .Math .max ;
43import static net .bytebuddy .jar .asm .Opcodes .ALOAD ;
54import static net .bytebuddy .jar .asm .Opcodes .ASTORE ;
6- import static net .bytebuddy .jar .asm .Opcodes .DUP ;
75import static net .bytebuddy .jar .asm .Opcodes .F_SAME ;
86import static net .bytebuddy .jar .asm .Opcodes .GOTO ;
97import static net .bytebuddy .jar .asm .Opcodes .H_INVOKESTATIC ;
8+ import static net .bytebuddy .jar .asm .Opcodes .IFNE ;
9+ import static net .bytebuddy .jar .asm .Opcodes .INVOKESTATIC ;
10+ import static net .bytebuddy .jar .asm .Opcodes .INVOKEVIRTUAL ;
1011
1112import datadog .context .Context ;
1213import datadog .trace .api .gateway .Flow ;
1314import datadog .trace .bootstrap .instrumentation .api .AgentSpan ;
15+ import datadog .trace .bootstrap .instrumentation .api .Java8BytecodeBridge ;
1416import datadog .trace .instrumentation .jetty .JettyBlockingHelper ;
1517import java .io .BufferedWriter ;
1618import java .io .FileOutputStream ;
3032 * Instruments the handle (or run) method to put the calls to <code>getServer().handle(this)</code>
3133 * under a condition, for the {@link org.eclipse.jetty.server.HttpChannel} class.
3234 *
33- * <p>In particular, for earlier versions of jetty: <code>
35+ * <p>In particular, for earlier versions of jetty:
36+ * <pre>
3437 * case REQUEST_DISPATCH:
3538 * // ...
3639 * getServer().handle(this);
37- * </code> is replaced with: <code>
40+ * </pre>
41+ * is replaced with:
42+ * <pre>
3843 * case REQUEST_DISPATCH:
3944 * // ...
40- * if (JettyBlockingHelper.block(this.getRequest(), this.getResponse(), context )) {
45+ * if (JettyBlockingHelper.block(this.getRequest(), this.getResponse(), Java8BytecodeBridge.getCurrentContext() )) {
4146 * // nothing
4247 * } else {
4348 * getServer().handle(this);
4449 * }
45- * </code> And for later versions of Jetty before 11.16.0, <code>
50+ * </pre>
51+ * And for later versions of Jetty before 11.16.0,
52+ * <pre>
4653 * case DISPATCH:
4754 * {
4855 * // ...
5158 * // ...
5259 * getServer().handle(HttpChannel.this);
5360 * });
54- * </code> is replaced with: <code>
61+ * </pre>
62+ * is replaced with:
63+ * <pre>
5564 * case DISPATCH:
5665 * {
5766 * // ...
6877 * getServer().handle(HttpChannel.this);
6978 * });
7079 * }
71- * </code> And for later versions of Jetty, <code>
80+ * </pre>
81+ * And for later versions of Jetty,
82+ * <pre>
7283 * case DISPATCH:
7384 * {
7485 * // ...
7586 * dispatch(DispatcherType.REQUEST, _requestDispatcher);
76- * </code> is replaced with: <code>
87+ * </pre>
88+ * is replaced with:
89+ * <pre>
7790 * case DISPATCH:
7891 * {
7992 * // ...
87100 * } else {
88101 * dispatch(DispatcherType.REQUEST, _requestDispatcher);
89102 * }
90- * </code >
103+ * </pre >
91104 */
92105public class HandleVisitor extends MethodVisitor {
93106 private static final Logger log = LoggerFactory .getLogger (HandleVisitor .class );
94- private static final int CONTEXT_VAR = 100 ;
107+ private static final int CONTEXT_VAR = 1000 ;
95108
96109 /** Whether the next store is supposed to store the Context variable. */
97110 private boolean lookForStore ;
98111 /** Whether the Context variable was stored to local index {@link #CONTEXT_VAR}. */
99112 private boolean contextStored ;
113+ // private int contextVarIndex = -1;
100114 /** Whether the handle() method injection was successful .*/
101115 private boolean success ;
102116 private final String methodName ;
@@ -129,13 +143,13 @@ DelayCertainInsMethodVisitor delayVisitorDelegate() {
129143 return (DelayCertainInsMethodVisitor ) this .mv ;
130144 }
131145
132- @ Override
133- public void visitLocalVariable (String name , String descriptor , String signature , Label start , Label end , int index ) {
134- if (contextStored && index == CONTEXT_VAR ) {
135- super .visitLocalVariable ("context" , Type .getDescriptor (Context .class ), null , start , end , CONTEXT_VAR );
136- }
137- super .visitLocalVariable (name , descriptor , signature , start , end , index );
138- }
146+ // @Override
147+ // public void visitLocalVariable(String name, String descriptor, String signature, Label start, Label end, int index) {
148+ // if (contextStored && index == CONTEXT_VAR) {
149+ // super.visitLocalVariable("context", Type.getDescriptor(Context.class), null, start, end, CONTEXT_VAR);
150+ // }
151+ // super.visitLocalVariable(name, descriptor, signature, start, end, index);
152+ // }
139153
140154 @ Override
141155 public void visitMethodInsn (
@@ -147,14 +161,14 @@ public void visitMethodInsn(
147161 if (!contextStored ) {
148162 lookForStore =
149163 !lookForStore
150- && opcode == Opcodes . INVOKEVIRTUAL
164+ && opcode == INVOKEVIRTUAL
151165 && name .equals ("startSpan" )
152166 && descriptor .endsWith ("Ldatadog/context/Context;" );
153167 if (lookForStore ) {
154168 debug ("Found store" );
155169 }
156170 } else if (!success
157- && opcode == Opcodes . INVOKEVIRTUAL
171+ && opcode == INVOKEVIRTUAL
158172 && owner .equals ("org/eclipse/jetty/server/Server" )
159173 && name .equals ("handle" )
160174 && descriptor .equals ("(Lorg/eclipse/jetty/server/HttpChannel;)V" )) {
@@ -177,32 +191,42 @@ public void visitMethodInsn(
177191
178192 // Declare label to insert after Server.handle() call
179193 Label afterHandle = new Label ();
180- // Inject blocking helper call
194+ // Inject blocking helper call and get its three parameters onto the stack:
195+ // - Request
196+ // - Response
197+ // - Context -- retrieved from current as attached just earlier from tracing instrumentation
181198 super .visitVarInsn (ALOAD , 0 );
182199 super .visitMethodInsn (
183- Opcodes . INVOKEVIRTUAL ,
200+ INVOKEVIRTUAL ,
184201 "org/eclipse/jetty/server/HttpChannel" ,
185202 "getRequest" ,
186203 "()Lorg/eclipse/jetty/server/Request;" ,
187204 false );
188205 super .visitVarInsn (ALOAD , 0 );
189206 super .visitMethodInsn (
190- Opcodes . INVOKEVIRTUAL ,
207+ INVOKEVIRTUAL ,
191208 "org/eclipse/jetty/server/HttpChannel" ,
192209 "getResponse" ,
193210 "()Lorg/eclipse/jetty/server/Response;" ,
194211 false );
195- super .visitVarInsn (ALOAD , CONTEXT_VAR );
196212 super .visitMethodInsn (
197- Opcodes .INVOKESTATIC ,
213+ INVOKESTATIC ,
214+ Type .getInternalName (Java8BytecodeBridge .class ),
215+ "getCurrentContext" ,
216+ "()Ldatadog/context/Context;" ,
217+ false
218+ );
219+ // super.visitVarInsn(ALOAD, CONTEXT_VAR);
220+ super .visitMethodInsn (
221+ INVOKESTATIC ,
198222 Type .getInternalName (JettyBlockingHelper .class ),
199223 "block" ,
200224 "(Lorg/eclipse/jetty/server/Request;Lorg/eclipse/jetty/server/Response;"
201225 + Type .getDescriptor (Context .class )
202226 + ")Z" ,
203227 false );
204228 // Inject jump to after Server.handle() call if blocked
205- super .visitJumpInsn (Opcodes . IFNE , afterHandle );
229+ super .visitJumpInsn (IFNE , afterHandle );
206230 // Inject getServer() and Server.handle() calls
207231 mv .commitVisitations (savedVisitations );
208232 super .visitMethodInsn (opcode , owner , name , descriptor , isInterface );
@@ -213,7 +237,7 @@ public void visitMethodInsn(
213237 this .success = true ;
214238 return ;
215239 } else if (!success
216- && (opcode == Opcodes .INVOKESPECIAL || opcode == Opcodes . INVOKEVIRTUAL )
240+ && (opcode == Opcodes .INVOKESPECIAL || opcode == INVOKEVIRTUAL )
217241 && owner .equals ("org/eclipse/jetty/server/HttpChannel" )
218242 && name .equals ("dispatch" )
219243 && (descriptor .equals (
@@ -265,14 +289,14 @@ public void visitMethodInsn(
265289 // RequestBlockingAction, AgentSpan)
266290 super .visitVarInsn (ALOAD , 0 );
267291 super .visitMethodInsn (
268- Opcodes . INVOKEVIRTUAL ,
292+ INVOKEVIRTUAL ,
269293 "org/eclipse/jetty/server/HttpChannel" ,
270294 "getRequest" ,
271295 "()Lorg/eclipse/jetty/server/Request;" ,
272296 false );
273297 super .visitVarInsn (ALOAD , 0 );
274298 super .visitMethodInsn (
275- Opcodes . INVOKEVIRTUAL ,
299+ INVOKEVIRTUAL ,
276300 "org/eclipse/jetty/server/HttpChannel" ,
277301 "getResponse" ,
278302 "()Lorg/eclipse/jetty/server/Response;" ,
@@ -369,18 +393,19 @@ public void visitVarInsn(int opcode, int varIndex) {
369393 debug ("Found context" );
370394 contextStored = true ;
371395 lookForStore = false ;
396+ // contextVarIndex = varIndex;
372397 // Duplicate on stack and store to its own local var
373- super .visitInsn (DUP );
374- super .visitVarInsn (ASTORE , CONTEXT_VAR );
398+ // super.visitInsn(DUP);
399+ // super.visitVarInsn(ASTORE, CONTEXT_VAR);
375400 }
376401 super .visitVarInsn (opcode , varIndex );
377402 }
378403
379- @ Override
380- public void visitMaxs (int maxStack , int maxLocals ) {
381- debug ("VisitMaxs stack: " + maxStack + ", locals: " + maxLocals );
382- super .visitMaxs (maxStack , max (maxLocals , CONTEXT_VAR + 1 ));
383- }
404+ // @Override
405+ // public void visitMaxs(int maxStack, int maxLocals) {
406+ // debug("VisitMaxs stack: " + maxStack + ", locals: " + maxLocals);
407+ // super.visitMaxs(maxStack, max(maxLocals, CONTEXT_VAR + 1));
408+ // }
384409
385410 @ Override
386411 public void visitEnd () {
0 commit comments