MCPcopy Index your code
hub / github.com/clojure/clojure / visitLabel

Method visitLabel

src/jvm/clojure/asm/MethodWriter.java:1200–1275  ·  view source on GitHub ↗
(final Label label)

Source from the content-addressed store, hash-verified

1198 }
1199
1200 @Override
1201 public void visitLabel(final Label label) {
1202 // Resolve the forward references to this label, if any.
1203 hasAsmInstructions |= label.resolve(code.data, code.length);
1204 // visitLabel starts a new basic block (except for debug only labels), so we need to update the
1205 // previous and current block references and list of successors.
1206 if ((label.flags & Label.FLAG_DEBUG_ONLY) != 0) {
1207 return;
1208 }
1209 if (compute == COMPUTE_ALL_FRAMES) {
1210 if (currentBasicBlock != null) {
1211 if (label.bytecodeOffset == currentBasicBlock.bytecodeOffset) {
1212 // We use {@link Label#getCanonicalInstance} to store the state of a basic block in only
1213 // one place, but this does not work for labels which have not been visited yet.
1214 // Therefore, when we detect here two labels having the same bytecode offset, we need to
1215 // - consolidate the state scattered in these two instances into the canonical instance:
1216 currentBasicBlock.flags |= (label.flags & Label.FLAG_JUMP_TARGET);
1217 // - make sure the two instances share the same Frame instance (the implementation of
1218 // {@link Label#getCanonicalInstance} relies on this property; here label.frame should be
1219 // null):
1220 label.frame = currentBasicBlock.frame;
1221 // - and make sure to NOT assign 'label' into 'currentBasicBlock' or 'lastBasicBlock', so
1222 // that they still refer to the canonical instance for this bytecode offset.
1223 return;
1224 }
1225 // End the current basic block (with one new successor).
1226 addSuccessorToCurrentBasicBlock(Edge.JUMP, label);
1227 }
1228 // Append 'label' at the end of the basic block list.
1229 if (lastBasicBlock != null) {
1230 if (label.bytecodeOffset == lastBasicBlock.bytecodeOffset) {
1231 // Same comment as above.
1232 lastBasicBlock.flags |= (label.flags & Label.FLAG_JUMP_TARGET);
1233 // Here label.frame should be null.
1234 label.frame = lastBasicBlock.frame;
1235 currentBasicBlock = lastBasicBlock;
1236 return;
1237 }
1238 lastBasicBlock.nextBasicBlock = label;
1239 }
1240 lastBasicBlock = label;
1241 // Make it the new current basic block.
1242 currentBasicBlock = label;
1243 // Here label.frame should be null.
1244 label.frame = new Frame(label);
1245 } else if (compute == COMPUTE_INSERTED_FRAMES) {
1246 if (currentBasicBlock == null) {
1247 // This case should happen only once, for the visitLabel call in the constructor. Indeed, if
1248 // compute is equal to COMPUTE_INSERTED_FRAMES, currentBasicBlock stays unchanged.
1249 currentBasicBlock = label;
1250 } else {
1251 // Update the frame owner so that a correct frame offset is computed in Frame.accept().
1252 currentBasicBlock.frame.owner = label;
1253 }
1254 } else if (compute == COMPUTE_MAX_STACK_AND_LOCAL) {
1255 if (currentBasicBlock != null) {
1256 // End the current basic block (with one new successor).
1257 currentBasicBlock.outputStackMax = (short) maxRelativeStackSize;

Callers 7

MethodWriterMethod · 0.95
visitVarInsnMethod · 0.95
visitJumpInsnMethod · 0.95
compileMethod · 0.45
acceptMethod · 0.45
readCodeMethod · 0.45
markMethod · 0.45

Calls 2

resolveMethod · 0.45

Tested by

no test coverage detected