// Create a conflict resolution stub for the set of interface method signatures l.
  //
  public static ArchitectureSpecific.VM_CodeArray createStub(int[] sigIds, VM_Method[] targets) {
    // (1) Create an assembler.
    int numEntries = sigIds.length;
    VM_Assembler asm =
        new ArchitectureSpecific.VM_Assembler(numEntries); // pretend each entry is a bytecode

    // (2) signatures must be in ascending order (to build binary search tree).
    if (VM.VerifyAssertions) {
      for (int i = 1; i < sigIds.length; i++) {
        VM._assert(sigIds[i - 1] < sigIds[i]);
      }
    }

    // (3) Assign synthetic bytecode numbers to each switch such that we'll generate them
    // in ascending order.  This lets us use the general forward branching mechanisms
    // of the VM_Assembler.
    int[] bcIndices = new int[numEntries];
    assignBytecodeIndices(0, bcIndices, 0, numEntries - 1);

    // (4) Generate the stub.
    insertStubPrologue(asm);
    insertStubCase(asm, sigIds, targets, bcIndices, 0, numEntries - 1);

    ArchitectureSpecific.VM_CodeArray stub = asm.makeMachineCode().getInstructions();

    // (5) synchronize icache with generated machine code that was written through dcache
    if (VM.runningVM)
      VM_Memory.sync(VM_Magic.objectAsAddress(stub), stub.length() << LG_INSTRUCTION_WIDTH);

    return stub;
  }
 // Generate a subtree covering from low to high inclusive.
 private static void insertStubCase(
     VM_Assembler asm, int[] sigIds, VM_Method[] targets, int[] bcIndices, int low, int high) {
   int middle = (high + low) / 2;
   asm.resolveForwardReferences(bcIndices[middle]);
   if (low == middle && middle == high) {
     // a leaf case; can simply invoke the method directly.
     VM_Method target = targets[middle];
     if (target.isStatic()) {
       // an error case.
       asm.emitLAddrToc(S0, target.getOffset());
     } else {
       asm.emitLAddrOffset(S0, S0, target.getOffset());
     }
     asm.emitMTCTR(S0);
     asm.emitBCCTR();
   } else {
     asm.emitCMPI(S1, sigIds[middle]);
     if (low < middle) {
       asm.emitShortBC(LT, 0, bcIndices[(low + middle - 1) / 2]);
     }
     if (middle < high) {
       asm.emitShortBC(GT, 0, bcIndices[(middle + 1 + high) / 2]);
     }
     // invoke the method for middle.
     VM_Method target = targets[middle];
     if (target.isStatic()) {
       // an error case.
       asm.emitLAddrToc(S0, target.getOffset());
     } else {
       asm.emitLAddrOffset(S0, S0, target.getOffset());
     }
     asm.emitMTCTR(S0);
     asm.emitBCCTR();
     // Recurse.
     if (low < middle) {
       insertStubCase(asm, sigIds, targets, bcIndices, low, middle - 1);
     }
     if (middle < high) {
       insertStubCase(asm, sigIds, targets, bcIndices, middle + 1, high);
     }
   }
 }