public void instructionExecuted(JVM vm) {
    ThreadInfo ti = vm.getLastThreadInfo();
    Instruction insn = vm.getLastInstruction();

    if (insn instanceof VirtualInvocation) {

      if (vm.getNextInstruction() != insn) { // otherwise we didn't execute
        VirtualInvocation call = (VirtualInvocation) insn;
        int ref = call.getCalleeThis(ti);
        Record rec = getRecord(ref);

        if (rec != null) {
          MethodInfo mi = call.getInvokedMethod(ti, ref);

          if (logCall) {
            log(ti, "invoke %1$s.%2$s", rec.ei, mi.getUniqueName());
          }

          if (!checkShared(rec, ti, mi, insn)) {
            return;
          }
        }
      }

    } else if (insn instanceof PUTFIELD) {
      PUTFIELD storeInsn = (PUTFIELD) insn;
      int ref = storeInsn.getLastThis();
      Record rec = getRecord(ref);

      if (rec != null) {
        FieldInfo fi = storeInsn.getFieldInfo();

        if (logPut) {
          log(ti, "put %1$s.%2$s = <%3$d>", rec.ei, fi.getName(), storeInsn.getLastValue());
        }

        if (!checkShared(rec, ti, fi, insn)) {
          return;
        }

        if (!checkConst(rec, ti, fi, insn)) {
          return;
        }
      }
    }
  }
  static String toStringSymbolicRef(MJIEnv env, int objvRef) {
    if (objvRef == -1) {
      sequence += "[";
      sequence += "null";
      sequence += "]";

    } else {
      ClassInfo ci = env.getClassInfo(objvRef);
      // ElementInfo ei = DynamicArea.getHeap().get(objvRef);
      ElementInfo ei = JVM.getVM().getHeap().get(objvRef);
      sequence += "[" + objvRef + "]";
      if (!discovered.contains(new Integer(objvRef))) {
        discovered.add(new Integer(objvRef));
        sequence += "{";

        FieldInfo[] fields = ci.getDeclaredInstanceFields();

        for (int i = 0; i < fields.length; i++) {
          FieldInfo fi = fields[i];
          String fname = fi.getName();
          Object attr = ei.getFieldAttr(fi);

          if (fi instanceof ReferenceFieldInfo) {
            // System.out.println("field name " + fname);

            sequence += fname + ":";
            int ref = env.getReferenceField(objvRef, fname);
            // check if field is symbolic

            if (attr != null) // we reached a symbolic heap node
            sequence += "*";
            else toStringSymbolicRef(env, ref);
          } else {

            // System.out.println("field name " + fname);

            if (attr != null) // we reached a symbolic primitive field
            sequence += fname + ":" + (Expression) attr + " ";
            else {
              sequence += fname + ":" + fi.valueToString(ei.getFields()) + " ";
              // etc: use FieldInfo.valueToString(fields)
            }
          }
        }
        sequence += "}";
      }

      FieldInfo[] staticFields = ci.getDeclaredStaticFields();
      if (staticFields != null && staticFields.length > 0) {

        if (!discoveredClasses.contains(ci)) {
          sequence += "\n STATICS:";
          discoveredClasses.add(ci);
          sequence += "{";

          for (int i = 0; i < staticFields.length; i++) {
            FieldInfo fi = staticFields[i];
            String fname = fi.getName();

            StaticElementInfo sei = ci.getStaticElementInfo();
            if (sei == null) {
              ci.registerClass(env.getVM().getCurrentThread());
            }
            Object attr = sei.getFieldAttr(staticFields[i]);

            if (staticFields[i] instanceof ReferenceFieldInfo) {

              // System.out.println("field name " + fname);
              sequence += fname + ":";
              int refStatic = env.getStaticReferenceField(ci.getName(), fname);

              if (attr != null) // we reached a symbolic heap node
              sequence += "*";
              else toStringSymbolicRef(env, refStatic);
            } else {
              if (attr != null) // we reached a symbolic primitive node
              sequence += fname + ":" + (Expression) attr + " ";
              else sequence += fname + ":" + fi.valueToString(sei.getFields()) + " ";
            }
          }
          sequence += "}";
        }
      }
    }
    return sequence;
  }