public EntryPointPrototype getEntryPrototype(AddrCtx pcCtx, JitPassageDecoder decoder) {
		/**
		 * NOTE: It is possible for a race condition, still, if (very likely) the passage provides
		 * multiple entry points. It's not ideal, but still correct, I think, if this happens.
		 */
		CompletableFuture<EntryPointPrototype> proto;
		boolean wasAbsent;
		synchronized (codeCache) {
			proto = codeCache.get(pcCtx);
			wasAbsent = proto == null;
			if (wasAbsent) {
				proto = new CompletableFuture<>();
				codeCache.put(pcCtx, proto);
				// Won't know to put other entry points, yet
			}
		}
		/**
		 * TODO: I'm not sure it makes sense to do this computation without the lock.
		 * 
		 * On the one hand, it allows threads to avoid stalling on every translation, and instead
		 * only on translations for the same entry point. However, if we do keep the lock, then we
		 * can avoid the race condition on alternative entry points.
		 */

		if (wasAbsent) {
			/**
			 * Go ahead and use this thread instead of spawning another, because this one can't
			 * proceed until compilation is completed, anyway.
			 */
			try {
				JitCompiledPassageClass compiled = compileWithMaxOpsBackoff(pcCtx, decoder);
				synchronized (codeCache) {
					for (Entry<AddrCtx, EntryPointPrototype> ent : compiled.getBlockEntries()
							.entrySet()) {
						if (ent.getKey().equals(pcCtx)) {
							proto.complete(ent.getValue());
						}
						else {
							codeCache.put(ent.getKey(),
								CompletableFuture.completedFuture(ent.getValue()));
						}
					}
				}
			}
			catch (Throwable t) {
				proto.completeExceptionally(t);
			}
		}
		try {
			return proto.get();
		}
		catch (InterruptedException e) {
			throw new AssertionError(e);
		}
		catch (ExecutionException e) {
			return ExceptionUtils.rethrow(e);
		}
	}
Get the entry prototype for a given address and contextreg value.

<p>
An <b>entry prototype</b> is a class representing a translated passage and an index
identifying the point at which to enter the passage. The compiler numbers each entry point it
generates and provides those indices via a static field in the output class. Those entry
point indices are entered into the code cache for each translated passage. If no entry point
exists for the requested address and contextreg value, the emulator will decode and translate
a new passage at the requested seed.

<p>
It's a bit odd to take the thread's decoder for a machine-level thing; however, all thread
decoders ought to have the same behavior. The particular thread's decoder will have better
cached instruction block state for decoding in the vicinity of its past execution, though.

@param pcCtx the counter and decoder context
@param decoder the thread's decoder needing this entry point prototype
@return the entry point prototype
@see JitPcodeThread#getEntry(AddrCtx)
Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/emu/jit/JitPcodeEmulator.java