/*
 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

package sun.jvm.hotspot.ui.classbrowser;

import java.io.*;
import java.util.*;
import sun.jvm.hotspot.asm.*;
import sun.jvm.hotspot.code.*;
import sun.jvm.hotspot.compiler.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.interpreter.*;
import sun.jvm.hotspot.memory.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.tools.jcore.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.utilities.*;

public class HTMLGenerator implements /* imports */ ClassConstants {
    static class Formatter {
        boolean html;
        StringBuffer buf = new StringBuffer();

        Formatter(boolean h) {
            html = h;
        }

        void append(String s) {
            buf.append(s);
        }

        void append(int s) {
            buf.append(s);
        }

        void append(char s) {
            buf.append(s);
        }

        void append(StringBuffer s) {
            buf.append(s);
        }

        void append(Formatter s) {
            buf.append(s);
        }

        StringBuffer getBuffer() {
            return buf;
        }

        public String toString() {
            return buf.toString();
        }

        void wrap(String tag, String text) {
            wrap(tag, tag, text);
        }
        void wrap(String before, String after, String text) {
            beginTag(before);
            append(text);
            endTag(after);
        }

        // header tags
        void h1(String s) { nl(); wrap("h1", s); nl(); }
        void h2(String s) { nl(); wrap("h2", s); nl(); }
        void h3(String s) { nl(); wrap("h3", s); nl(); }
        void h4(String s) { nl(); wrap("h4", s); nl(); }

        // list tags
        void beginList()  { beginTag("ul"); nl(); }
        void endList()    { endTag("ul"); nl();   }
        void beginListItem() { beginTag("li"); }
        void endListItem()   { endTag("li"); nl();   }
        void li(String s) { wrap("li", s); nl();  }

        // table tags
        void beginTable(int border) {
            beginTag("table border='" + border + "'");
        }
        void cell(String s) { wrap("td", s); }
        void headerCell(String s) { wrap("th", s); }
        void endTable() { endTag("table"); }

        void link(String href, String text) {
            wrap("a href='" + href + "'", "a", text);
        }
        void beginTag(String s) {
            if (html) { append("<"); append(s); append(">"); }
        }
        void endTag(String s) {
            if (html) {
               append("</"); append(s); append(">");
            } else {
               if (s.equals("table") || s.equals("tr")) {
                  nl();
               }
               if (s.equals("td") || s.equals("th")) {
                  append(" ");
               }
            }
        }
        void bold(String s) {
            wrap("b", s);
        }

        void nl() {
            if (!html) buf.append("\n");
        }

        void br() {
            if (html) append("<br>");
            else      append("\n");
        }
        void genEmptyHTML() {
            if (html) append("<html></html>");
        }

        void genHTMLPrologue() {
            if (html) append("<html><body>");
        }

        void genHTMLPrologue(String title) {
            if (html) {
                append("<html><head><title>");
                append(title);
                append("</title></head>");
                append("<body>");
            }
            h2(title);
        }
        void genHTMLEpilogue() {
            if (html) append("</body></html>");
        }

    }

   private static final String DUMP_KLASS_OUTPUT_DIR = ".";
   private static final int NATIVE_CODE_SIZE = 200;
   private final String spaces;
   private final String tab;

   private boolean genHTML = true;

   public HTMLGenerator() {
       this(true);
   }

   public HTMLGenerator(boolean html) {
       genHTML = html;
       if (html) {
           spaces = "&nbsp;&nbsp;";
           tab = "&nbsp;&nbsp;&nbsp;&nbsp;";
       } else {
           spaces = "  ";
           tab = "    ";
       }
   }

   protected String escapeHTMLSpecialChars(String value) {
      if (!genHTML) return value;

      Formatter buf = new Formatter(genHTML);
      int len = value.length();
      for (int i=0; i < len; i++) {
         char c = value.charAt(i);
         switch (c) {
            case '<':
               buf.append("&lt;");
               break;
            case '>':
               buf.append("&gt;");
               break;
            case '&':
               buf.append("&amp;");
               break;
            default:
               buf.append(c);
               break;
         }
      }
      return buf.toString();
   }

   public String genHTMLForMessage(String message) {
      Formatter buf = new Formatter(genHTML);
      buf.genHTMLPrologue(message);
      buf.genHTMLEpilogue();
      return buf.toString();
   }

   public String genHTMLErrorMessage(Exception exp) {
      exp.printStackTrace();
      return genHTMLForMessage(exp.getClass().getName() + " : " + exp.getMessage());
   }

   public String genHTMLForWait(String message) {
      Formatter buf = new Formatter(genHTML);
      buf.genHTMLPrologue("Please wait ..");
      buf.h2(message);
      return buf.toString();
   }

   protected String genKlassTitle(InstanceKlass klass) {
      Formatter buf = new Formatter(genHTML);
      AccessFlags acc = klass.getAccessFlagsObj();
      if (acc.isPublic()) {
         buf.append("public ");
      } else if (acc.isProtected()) {
         buf.append("protected ");
      } else if (acc.isPrivate()) {
         buf.append("private ");
      }

      if (acc.isStatic()) {
         buf.append("static ");
      }

      if (acc.isAbstract() ) {
         buf.append("abstract ");
      } else if (acc.isFinal()) {
         buf.append("final ");
      }

      if (acc.isStrict()) {
         buf.append("strict ");
      }

      // javac generated flags
      if (acc.isEnum()) {
         buf.append("[enum] ");
      }
      if (acc.isSynthetic()) {
         buf.append("[synthetic] ");
      }

      if (klass.isInterface()) {
         buf.append("interface");
      } else {
         buf.append("class");
      }

      buf.append(' ');
      buf.append(klass.getName().asString().replace('/', '.'));
      // is it generic?
      Symbol genSig = klass.getGenericSignature();
      if (genSig != null) {
         buf.append(" [signature ");
         buf.append(escapeHTMLSpecialChars(genSig.asString()));
         buf.append("] ");
      } else {
         buf.append(' ');
      }
      buf.append('@');
      buf.append(klass.getAddress().toString());
      return buf.toString();
   }

   protected String genBaseHref() {
      return "";
   }

   protected String genKlassHref(InstanceKlass klass) {
      return genBaseHref() + "klass=" + klass.getAddress();
   }

   protected String genKlassLink(InstanceKlass klass) {
      Formatter buf = new Formatter(genHTML);
      buf.link(genKlassHref(klass), genKlassTitle(klass));
      return buf.toString();
   }

   protected String genMethodModifierString(AccessFlags acc) {
      Formatter buf = new Formatter(genHTML);
      if (acc.isPrivate()) {
         buf.append("private ");
      } else if (acc.isProtected()) {
         buf.append("protected ");
      } else if (acc.isPublic()) {
         buf.append("public ");
      }

      if (acc.isStatic()) {
         buf.append("static ");
      } else if (acc.isAbstract() ) {
         buf.append("abstract ");
      } else if (acc.isFinal()) {
         buf.append("final ");
      }

       if (acc.isNative()) {
         buf.append("native ");
      }

      if (acc.isStrict()) {
         buf.append("strict ");
      }

      if (acc.isSynchronized()) {
         buf.append("synchronized ");
      }

      // javac generated flags
      if (acc.isBridge()) {
         buf.append("[bridge] ");
      }

      if (acc.isSynthetic()) {
         buf.append("[synthetic] ");
      }

      if (acc.isVarArgs()) {
         buf.append("[varargs] ");
      }

      return buf.toString();
   }

   protected String genMethodNameAndSignature(Method method) {
      Formatter buf = new Formatter(genHTML);
      buf.append(genMethodModifierString(method.getAccessFlagsObj()));
      Symbol sig = method.getSignature();
      new SignatureConverter(sig, buf.getBuffer()).iterateReturntype();
      buf.append(" ");
      String methodName = method.getName().asString();
      buf.append(escapeHTMLSpecialChars(methodName));
      buf.append('(');
      new SignatureConverter(sig, buf.getBuffer()).iterateParameters();
      buf.append(')');
      // is it generic?
      Symbol genSig = method.getGenericSignature();
      if (genSig != null) {
         buf.append(" [signature ");
         buf.append(escapeHTMLSpecialChars(genSig.asString()));
         buf.append("] ");
      }
      return buf.toString().replace('/', '.');
   }

   protected String genMethodTitle(Method method) {
      Formatter buf = new Formatter(genHTML);
      buf.append(genMethodNameAndSignature(method));
      buf.append(' ');
      buf.append('@');
      buf.append(method.getAddress().toString());
      return buf.toString();
   }

   protected String genMethodHref(Method m) {
      return genBaseHref() + "method=" + m.getAddress();
   }

   protected String genMethodLink(Method m) {
      Formatter buf = new Formatter(genHTML);
      buf.link(genMethodHref(m), genMethodTitle(m));
      return buf.toString();
   }

   protected String genMethodAndKlassLink(Method m) {
      Formatter buf = new Formatter(genHTML);
      buf.append(genMethodLink(m));
      buf.append(" of ");
      buf.append(genKlassLink((InstanceKlass) m.getMethodHolder()));
      return buf.toString();
   }

   protected String genNMethodHref(NMethod nm) {
      return genBaseHref() + "nmethod=" + nm.getAddress();
   }

   public String genNMethodTitle(NMethod nmethod) {
      Formatter buf = new Formatter(genHTML);
      Method m = nmethod.getMethod();

      buf.append("Disassembly for compiled method [");
      buf.append(genMethodTitle(m));
      buf.append(" ] ");
      buf.append('@');
      buf.append(nmethod.getAddress().toString());
      return buf.toString();
   }

   protected String genNMethodLink(NMethod nm) {
      Formatter buf = new Formatter(genHTML);
      buf.link(genNMethodHref(nm), genNMethodTitle(nm));
      return buf.toString();
   }

   public String genCodeBlobTitle(CodeBlob blob) {
      Formatter buf = new Formatter(genHTML);
      buf.append("Disassembly for code blob " + blob.getName() + " [");
      buf.append(blob.getClass().getName());
      buf.append(" ] @");
      buf.append(blob.getAddress().toString());
      return buf.toString();
   }

   protected BytecodeDisassembler createBytecodeDisassembler(Method m) {
      return new BytecodeDisassembler(m);
   }

   private String genLowHighShort(int val) {
      Formatter buf = new Formatter(genHTML);
      buf.append('#');
      buf.append(Integer.toString(val & 0xFFFF));
      buf.append(" #");
      buf.append(Integer.toString((val >> 16) & 0xFFFF));
      return buf.toString();
   }

   private String genListOfShort(short[] values) {
      if (values == null || values.length == 0)  return "";
      Formatter buf = new Formatter(genHTML);
      buf.append('[');
      for (int i = 0; i < values.length; i++) {
          if (i > 0)  buf.append(' ');
          buf.append('#');
          buf.append(Integer.toString(values[i]));
      }
      buf.append(']');
      return buf.toString();
   }

   protected String genHTMLTableForConstantPool(ConstantPool cpool) {
      Formatter buf = new Formatter(genHTML);
      buf.beginTable(1);

      buf.beginTag("tr");
      buf.headerCell("Index");
      buf.headerCell("Constant Type");
      buf.headerCell("Constant Value");
      buf.endTag("tr");

      final int length = (int) cpool.getLength();
      // zero'th pool entry is always invalid. ignore it.
      for (int index = 1; index < length; index++) {
         buf.beginTag("tr");
         buf.cell(Integer.toString(index));

         int ctag = (int) cpool.getTags().at((int) index);
         switch (ctag) {
            case JVM_CONSTANT_Integer:
               buf.cell("JVM_CONSTANT_Integer");
               buf.cell(Integer.toString(cpool.getIntAt(index)));
               break;

            case JVM_CONSTANT_Float:
               buf.cell("JVM_CONSTANT_Float");
               buf.cell(Float.toString(cpool.getFloatAt(index)));
               break;

            case JVM_CONSTANT_Long:
               buf.cell("JVM_CONSTANT_Long");
               buf.cell(Long.toString(cpool.getLongAt(index)));
               // long entries occupy two slots
               index++;
               break;

            case JVM_CONSTANT_Double:
               buf.cell("JVM_CONSTANT_Double");
               buf.cell(Double.toString(cpool.getDoubleAt(index)));
               // double entries occupy two slots
               index++;
               break;

            case JVM_CONSTANT_UnresolvedClass:
               buf.cell("JVM_CONSTANT_UnresolvedClass");
               buf.cell(cpool.getKlassNameAt(index).asString());
               break;

            case JVM_CONSTANT_UnresolvedClassInError:
               buf.cell("JVM_CONSTANT_UnresolvedClassInError");
               buf.cell(cpool.getSymbolAt(index).asString());
               break;

            case JVM_CONSTANT_Class:
               buf.cell("JVM_CONSTANT_Class");
               Klass klass = (Klass) cpool.getKlassAt(index);
               if (klass instanceof InstanceKlass) {
                  buf.cell(genKlassLink((InstanceKlass) klass));
               } else {
                  buf.cell(klass.getName().asString().replace('/', '.'));
               }
               break;

            case JVM_CONSTANT_Utf8:
               buf.cell("JVM_CONSTANT_Utf8");
               buf.cell("\"" +
                 escapeHTMLSpecialChars(cpool.getSymbolAt(index).asString()) +
                 "\"");
               break;

            case JVM_CONSTANT_String:
               buf.cell("JVM_CONSTANT_String");
               buf.cell("\"" +
                        escapeHTMLSpecialChars(cpool.getUnresolvedStringAt(index).asString()) + "\"");
               break;

            case JVM_CONSTANT_Fieldref:
               buf.cell("JVM_CONSTANT_Fieldref");
               buf.cell(genLowHighShort(cpool.getIntAt(index)));
               break;

            case JVM_CONSTANT_Methodref:
               buf.cell("JVM_CONSTANT_Methodref");
               buf.cell(genLowHighShort(cpool.getIntAt(index)));
               break;

            case JVM_CONSTANT_InterfaceMethodref:
               buf.cell("JVM_CONSTANT_InterfaceMethodref");
               buf.cell(genLowHighShort(cpool.getIntAt(index)));
               break;

            case JVM_CONSTANT_NameAndType:
               buf.cell("JVM_CONSTANT_NameAndType");
               buf.cell(genLowHighShort(cpool.getIntAt(index)));
               break;

            case JVM_CONSTANT_ClassIndex:
               buf.cell("JVM_CONSTANT_ClassIndex");
               buf.cell(Integer.toString(cpool.getIntAt(index)));
               break;

            case JVM_CONSTANT_StringIndex:
               buf.cell("JVM_CONSTANT_StringIndex");
               buf.cell(Integer.toString(cpool.getIntAt(index)));
               break;

            case JVM_CONSTANT_MethodHandle:
               buf.cell("JVM_CONSTANT_MethodHandle");
               buf.cell(genLowHighShort(cpool.getIntAt(index)));
               break;

            case JVM_CONSTANT_MethodType:
               buf.cell("JVM_CONSTANT_MethodType");
               buf.cell(Integer.toString(cpool.getIntAt(index)));
               break;

            case JVM_CONSTANT_InvokeDynamic:
               buf.cell("JVM_CONSTANT_InvokeDynamic");
               buf.cell(genLowHighShort(cpool.getIntAt(index)) +
                        genListOfShort(cpool.getBootstrapSpecifierAt(index)));
               break;

            default:
               throw new InternalError("unknown tag: " + ctag);
         }

         buf.endTag("tr");
      }

      buf.endTable();
      return buf.toString();
   }

   public String genHTML(ConstantPool cpool) {
      try {
         Formatter buf = new Formatter(genHTML);
         buf.genHTMLPrologue(genConstantPoolTitle(cpool));
         buf.h3("Holder Class");
         buf.append(genKlassLink((InstanceKlass) cpool.getPoolHolder()));
         buf.h3("Constants");
         buf.append(genHTMLTableForConstantPool(cpool));
         buf.genHTMLEpilogue();
         return buf.toString();
      } catch (Exception exp) {
         return genHTMLErrorMessage(exp);
      }
   }

   protected String genConstantPoolHref(ConstantPool cpool) {
      return genBaseHref() + "cpool=" + cpool.getAddress();
   }

   protected String genConstantPoolTitle(ConstantPool cpool) {
      Formatter buf = new Formatter(genHTML);
      buf.append("Constant Pool of [");
      buf.append(genKlassTitle((InstanceKlass) cpool.getPoolHolder()));
      buf.append("] @");
      buf.append(cpool.getAddress().toString());
      return buf.toString();
   }

   protected String genConstantPoolLink(ConstantPool cpool) {
      Formatter buf = new Formatter(genHTML);
      buf.link(genConstantPoolHref(cpool), genConstantPoolTitle(cpool));
      return buf.toString();
   }

   public String genHTML(Method method) {
      try {
         final Formatter buf = new Formatter(genHTML);
         buf.genHTMLPrologue(genMethodTitle(method));

         buf.h3("Holder Class");
         buf.append(genKlassLink((InstanceKlass) method.getMethodHolder()));

         NMethod nmethod = method.getNativeMethod();
         if (nmethod != null) {
            buf.h3("Compiled Code");
            buf.append(genNMethodLink(nmethod));
         }

         boolean hasThrows = method.hasCheckedExceptions();
         ConstantPool cpool = ((InstanceKlass) method.getMethodHolder()).getConstants();
         if (hasThrows) {
            buf.h3("Checked Exception(s)");
            CheckedExceptionElement[] exceptions = method.getCheckedExceptions();
            buf.beginTag("ul");
            for (int exp = 0; exp < exceptions.length; exp++) {
               short cpIndex = (short) exceptions[exp].getClassCPIndex();
               ConstantPool.CPSlot obj = cpool.getSlotAt(cpIndex);
               if (obj.isUnresolved()) {
                 buf.li((obj.getSymbol()).asString().replace('/', '.'));
               } else {
                 buf.li(genKlassLink((InstanceKlass)obj.getKlass()));
               }
            }
            buf.endTag("ul");
         }

         if (method.isNative() || method.isAbstract()) {
           buf.genHTMLEpilogue();
           return buf.toString();
         }

         buf.h3("Bytecode");
         BytecodeDisassembler disasm = createBytecodeDisassembler(method);
         final boolean hasLineNumbers = method.hasLineNumberTable();
         disasm.decode(new BytecodeVisitor() {
                          private Method method;
                          public void prologue(Method m) {
                             method = m;
                             buf.beginTable(0);
                             buf.beginTag("tr");
                             if (hasLineNumbers) {
                                buf.headerCell("line");
                             }
                             buf.headerCell("bci" + spaces);
                             buf.headerCell("bytecode");
                             buf.endTag("tr");
                          }

                          public void visit(Bytecode instr) {
                             int curBci = instr.bci();
                             buf.beginTag("tr");
                             if (hasLineNumbers) {
                                int lineNumber = method.getLineNumberFromBCI(curBci);
                                buf.cell(Integer.toString(lineNumber) + spaces);
                             }
                             buf.cell(Integer.toString(curBci) + spaces);

                             buf.beginTag("td");
                             String instrStr = null;
                             try {
                                 instrStr = escapeHTMLSpecialChars(instr.toString());
                             } catch (RuntimeException re) {
                                 buf.append("exception while printing " + instr.getBytecodeName());
                                 buf.endTag("td");
                                 buf.endTag("tr");
                                 re.printStackTrace();
                                 return;
                             }

                             if (instr instanceof BytecodeNew) {
                                BytecodeNew newBytecode = (BytecodeNew) instr;
                                InstanceKlass klass = newBytecode.getNewKlass();
                                if (klass != null) {
                                    buf.link(genKlassHref(klass), instrStr);
                                } else {
                                    buf.append(instrStr);
                                }
                             } else if(instr instanceof BytecodeInvoke) {
                                BytecodeInvoke invokeBytecode = (BytecodeInvoke) instr;
                                Method m = invokeBytecode.getInvokedMethod();
                                if (m != null) {
                                   buf.link(genMethodHref(m), instrStr);
                                   buf.append(" of ");
                                   InstanceKlass klass = (InstanceKlass) m.getMethodHolder();
                                   buf.link(genKlassHref(klass), genKlassTitle(klass));
                                } else {
                                   buf.append(instrStr);
                                }
                             } else if (instr instanceof BytecodeGetPut) {
                                BytecodeGetPut getPut = (BytecodeGetPut) instr;
                                sun.jvm.hotspot.oops.Field f = getPut.getField();
                                buf.append(instrStr);
                                if (f != null) {
                                   InstanceKlass klass = f.getFieldHolder();
                                   buf.append(" of ");
                                   buf.link(genKlassHref(klass), genKlassTitle(klass));
                                }
                             } else if (instr instanceof BytecodeLoadConstant) {
                                BytecodeLoadConstant ldc = (BytecodeLoadConstant) instr;
                                if (ldc.isKlassConstant()) {
                                   Object oop = ldc.getKlass();
                                   if (oop instanceof InstanceKlass) {
                                      buf.append("<a href='");
                                      buf.append(genKlassHref((InstanceKlass) oop));
                                      buf.append("'>");
                                      buf.append(instrStr);
                                      buf.append("</a>");
                                   } else {
                                      // unresolved klass literal
                                      buf.append(instrStr);
                                   }
                                } else {
                                   // not a klass literal
                                   buf.append(instrStr);
                                }
                             } else {
                                buf.append(instrStr);
                             }
                             buf.endTag("td");
                             buf.endTag("tr");
                          }

                          public void epilogue() {
                             buf.endTable();
                          }
                       });

         // display exception table for this method
         boolean hasException = method.hasExceptionTable();
         if (hasException) {
            ExceptionTableElement[] exceptionTable = method.getExceptionTable();
            int numEntries = exceptionTable.length;
            if (numEntries != 0) {
               buf.h4("Exception Table");
               buf.beginTable(1);
               buf.beginTag("tr");
               buf.headerCell("start bci");
               buf.headerCell("end bci");
               buf.headerCell("handler bci");
               buf.headerCell("catch type");
               buf.endTag("tr");

               for (int e = 0; e < numEntries; e ++) {
                  buf.beginTag("tr");
                  buf.cell(Integer.toString(exceptionTable[e].getStartPC()));
                  buf.cell(Integer.toString(exceptionTable[e].getEndPC()));
                  buf.cell(Integer.toString(exceptionTable[e].getHandlerPC()));
                  short cpIndex = (short) exceptionTable[e].getCatchTypeIndex();
                  ConstantPool.CPSlot obj = cpIndex == 0? null : cpool.getSlotAt(cpIndex);
                  if (obj == null) {
                     buf.cell("Any");
                  } else if (obj.isUnresolved()) {
                     buf.cell(obj.getSymbol().asString().replace('/', '.'));
                  } else {
                    buf.cell(genKlassLink((InstanceKlass)obj.getKlass()));
                  }
                  buf.endTag("tr");
               }

               buf.endTable();
            }
         }

         // display constant pool hyperlink
         buf.h3("Constant Pool");
         buf.append(genConstantPoolLink(cpool));
         buf.genHTMLEpilogue();
         return buf.toString();
      } catch (Exception exp) {
         return genHTMLErrorMessage(exp);
      }
   }

   protected SymbolFinder createSymbolFinder() {
      return new DummySymbolFinder();
   }

   // genHTML for a given address. Address may be a PC or
   // Method* or Klass*.

   public String genHTMLForAddress(String addrStr) {
      return genHTML(parseAddress(addrStr));
   }

   public String genHTML(sun.jvm.hotspot.debugger.Address pc) {
      CodeBlob blob = null;

      try {
         blob = (CodeBlob)VM.getVM().getCodeCache().findBlobUnsafe(pc);
      } catch (Exception exp) {
         // ignore
      }

      if (blob != null) {
         if (blob instanceof NMethod) {
            return genHTML((NMethod)blob);
         } else {
            // may be interpreter code.
            Interpreter interp = VM.getVM().getInterpreter();
            if (interp.contains(pc)) {
               InterpreterCodelet codelet = interp.getCodeletContaining(pc);
               if (codelet == null) {
                  return "Unknown location in the Interpreter: " + pc;
               }
               return genHTML(codelet);
            }
            return genHTML(blob);
         }
      } else if (VM.getVM().getCodeCache().contains(pc)) {
         return "Unknown location in the CodeCache: " + pc;
      }

      // did not find nmethod.
      // try Method*, Klass* and ConstantPool*.
      try {
        Metadata obj = Metadata.instantiateWrapperFor(pc);
         if (obj != null) {
            if (obj instanceof Method) {
               return genHTML((Method) obj);
            } else if (obj instanceof InstanceKlass) {
               return genHTML((InstanceKlass) obj);
            } else if (obj instanceof ConstantPool) {
               return genHTML((ConstantPool) obj);
            }
         }
      } catch (Exception exp) {
        exp.printStackTrace();
         // ignore
      }

      // didn't find any. do raw disassembly.
      return genHTMLForRawDisassembly(pc, null);
   }

   public String genHTMLForRawDisassembly(sun.jvm.hotspot.debugger.Address startPc, int size) {
      try {
         return genHTMLForRawDisassembly(startPc, size, null);
      } catch (Exception exp) {
         return genHTMLErrorMessage(exp);
      }
   }

   protected String genHTMLForRawDisassembly(sun.jvm.hotspot.debugger.Address startPc,
                                             String prevPCs) {
      try {
         return genHTMLForRawDisassembly(startPc, NATIVE_CODE_SIZE, prevPCs);
      } catch (Exception exp) {
         return genHTMLErrorMessage(exp);
      }
   }

   protected String genPCHref(long targetPc) {
      return genBaseHref() + "pc=0x" + Long.toHexString(targetPc);
   }

   protected String genMultPCHref(String pcs) {
      StringBuffer buf = new StringBuffer(genBaseHref());
      buf.append("pc_multiple=");
      buf.append(pcs);
      return buf.toString();
   }

   protected String genPCHref(Address addr) {
      return genPCHref(addressToLong(addr));
   }

   class HTMLDisassembler implements InstructionVisitor {
      private int instrSize = 0;
      private Formatter buf;
      private SymbolFinder symFinder = createSymbolFinder();
      private long pc;
      private OopMapSet oms;
      private CodeBlob blob;
      private NMethod nmethod;

      HTMLDisassembler(Formatter buf, CodeBlob blob) {
         this.buf = buf;
         this.blob = blob;
         if (blob != null) {
            if (blob instanceof NMethod) {
               nmethod = (NMethod)blob;
            }
            oms = blob.getOopMaps();
         }
      }

      public int getInstructionSize() {
         return  instrSize;
      }

      public void prologue() {
      }

      public void beginInstruction(long currentPc) {
         pc = currentPc;

         sun.jvm.hotspot.debugger.Address adr = longToAddress(pc);
         if (nmethod != null) {
            if (adr.equals(nmethod.getEntryPoint()))             print("[Entry Point]\n");
            if (adr.equals(nmethod.getVerifiedEntryPoint()))     print("[Verified Entry Point]\n");
            if (adr.equals(nmethod.exceptionBegin()))            print("[Exception Handler]\n");
            if (adr.equals(nmethod.stubBegin()) &&
                !nmethod.stubBegin().equals(nmethod.stubEnd()))  print("[Stub Code]\n");
            // if (adr.equals(nmethod.constsBegin()))               print("[Constants]\n");
         }

         buf.append(adr.toString());
         buf.append(':');
         buf.append(tab);
      }

      public void printAddress(long address) {
         sun.jvm.hotspot.debugger.Address addr = longToAddress(address);
         if (VM.getVM().getCodeCache().contains(addr)) {
            buf.link(genPCHref(address), addr.toString());
         } else {
            buf.append(addr.toString());
         }
      }

      public void print(String s) {
         buf.append(s);
      }

      public void endInstruction(long endPc) {
         instrSize += endPc - pc;
         if (genHTML) buf.br();

         if (nmethod != null) {
            ScopeDesc sd = nmethod.scope_desc_in(pc, endPc);
            if (sd != null) {
               buf.br();
               buf.append(genSafepointInfo(nmethod, sd));
            }
         }

         if (oms != null) {
            long base = addressToLong(blob.codeBegin());
            for (int i = 0, imax = (int)oms.getSize(); i < imax; i++) {
               OopMap om = oms.getMapAt(i);
               long omspc = base + om.getOffset();
               if (omspc > pc) {
                  if (omspc <= endPc) {
                     buf.br();
                     buf.append(genOopMapInfo(om));
                     // st.move_to(column);
                     // visitor.print("; ");
                        // om.print_on(st);
                  }
                  break;
               }
            }
         }
         // follow each complete insn by a nice newline
         buf.br();
      }

      public void epilogue() {
      }
   };

   protected String genHTMLForRawDisassembly(sun.jvm.hotspot.debugger.Address addr,
                                             int size,
                                             String prevPCs) {
      try {
         final Formatter buf = new Formatter(genHTML);
         buf.genHTMLPrologue("Disassembly @ " + addr);

         if (prevPCs != null && genHTML) {
             buf.beginTag("p");
             buf.link(genMultPCHref(prevPCs), "show previous code ..");
             buf.endTag("p");
         }


         buf.h3("Code");
         HTMLDisassembler visitor = new HTMLDisassembler(buf, null);
         Disassembler.decode(visitor, null, addr, addr.addOffsetTo(size));

         if (genHTML) buf.beginTag("p");
         Formatter tmpBuf = new Formatter(genHTML);
         long startPc = addressToLong(addr);
         tmpBuf.append("0x");
         tmpBuf.append(Long.toHexString(startPc + visitor.getInstructionSize()).toString());
         tmpBuf.append(",0x");
         tmpBuf.append(Long.toHexString(startPc));
         if (prevPCs != null) {
            tmpBuf.append(',');
            tmpBuf.append(prevPCs);
         }
         if (genHTML) {
             buf.link(genMultPCHref(tmpBuf.toString()), "show more code ..");
             buf.endTag("p");
         }

         buf.genHTMLEpilogue();
         return buf.toString();
      } catch (Exception exp) {
         return genHTMLErrorMessage(exp);
      }
   }

   protected String genSafepointInfo(NMethod nm, ScopeDesc sd) {
       Formatter buf = new Formatter(genHTML);
       Formatter tabs = new Formatter(genHTML);
       tabs.append(tab + tab + tab); // Initial indent for debug info

       buf.beginTag("pre");
       genScope(buf, tabs, sd);

       // Reset indent for scalar replaced objects
       tabs = new Formatter(genHTML);
       tabs.append(tab + tab + tab); // Initial indent for debug info

       genScObjInfo(buf, tabs, sd);
       buf.endTag("pre");

       return buf.toString();
   }

    protected void genScope(Formatter buf, Formatter tabs, ScopeDesc sd) {
        if (sd == null) {
            return;
        }

        genScope(buf, tabs, sd.sender());

        buf.append(tabs);
        Method m = sd.getMethod();
        buf.append(genMethodAndKlassLink(m));
        int bci = sd.getBCI();
        buf.append(" @ bci = ");
        buf.append(Integer.toString(bci));

        int line = m.getLineNumberFromBCI(bci);
        if (line != -1) {
            buf.append(", line = ");
            buf.append(Integer.toString(line));
        }

        List locals = sd.getLocals();
        if (locals != null) {
            buf.br();
            buf.append(tabs);
            buf.append(genHTMLForLocals(sd, locals));
        }

        List expressions = sd.getExpressions();
        if (expressions != null) {
            buf.br();
            buf.append(tabs);
            buf.append(genHTMLForExpressions(sd, expressions));
        }

        List monitors = sd.getMonitors();
        if (monitors != null) {
            buf.br();
            buf.append(tabs);
            buf.append(genHTMLForMonitors(sd, monitors));
        }

        buf.br();
        tabs.append(tab);
    }

    protected void genScObjInfo(Formatter buf, Formatter tabs, ScopeDesc sd) {
        if (sd == null) {
            return;
        }

        List objects = sd.getObjects();
        if (objects == null) {
            return;
        }
        int length = objects.size();
        for (int i = 0; i < length; i++) {
            buf.append(tabs);
            ObjectValue ov = (ObjectValue)objects.get(i);
            buf.append("ScObj" + i);
            ScopeValue sv = ov.getKlass();
            if (Assert.ASSERTS_ENABLED) {
                Assert.that(sv.isConstantOop(), "scalar replaced object klass must be constant oop");
            }
            ConstantOopReadValue klv = (ConstantOopReadValue)sv;
            OopHandle klHandle = klv.getValue();
            if (Assert.ASSERTS_ENABLED) {
                Assert.that(klHandle != null, "scalar replaced object klass must be not NULL");
            }
            Oop obj = VM.getVM().getObjectHeap().newOop(klHandle);
            // Obj is a Java mirror
            Klass klass = java_lang_Class.asKlass(obj);
            if (klass instanceof InstanceKlass) {
                InstanceKlass kls = (InstanceKlass) klass;
                buf.append(" " + kls.getName().asString() + "={");
                int flen = ov.fieldsSize();

                U2Array klfields = kls.getFields();
                int klen = (int) klfields.length();
                int findex = 0;
                for (int index = 0; index < klen; index++) {
                    int accsFlags = kls.getFieldAccessFlags(index);
                    Symbol f_name = kls.getFieldName(index);
                    AccessFlags access = new AccessFlags(accsFlags);
                    if (!access.isStatic()) {
                        ScopeValue svf = ov.getFieldAt(findex++);
                        String    fstr = scopeValueAsString(sd, svf);
                        buf.append(" [" + f_name.asString() + " :"+ index + "]=(#" + fstr + ")");
                    }
                }
                buf.append(" }");
            } else {
                buf.append(" ");
                int flen = ov.fieldsSize();
                if (klass instanceof TypeArrayKlass) {
                    TypeArrayKlass kls = (TypeArrayKlass) klass;
                    buf.append(kls.getElementTypeName() + "[" + flen + "]");
                } else if (klass instanceof ObjArrayKlass) {
                    ObjArrayKlass kls = (ObjArrayKlass) klass;
                    Klass elobj = kls.getBottomKlass();
                    if (elobj instanceof InstanceKlass) {
                        buf.append(elobj.getName().asString());
                    } else if (elobj instanceof TypeArrayKlass) {
                        TypeArrayKlass elkls = (TypeArrayKlass) elobj;
                        buf.append(elkls.getElementTypeName());
                    } else {
                        if (Assert.ASSERTS_ENABLED) {
                            Assert.that(false, "unknown scalar replaced object klass!");
                        }
                    }
                    buf.append("[" + flen + "]");
                    int ndim = (int) kls.getDimension();
                    while (--ndim > 0) {
                        buf.append("[]");
                    }
                } else {
                    if (Assert.ASSERTS_ENABLED) {
                        Assert.that(false, "unknown scalar replaced object klass!");
                    }
                }
                buf.append("={");
                for (int findex = 0; findex < flen; findex++) {
                    ScopeValue svf = ov.getFieldAt(findex);
                    String fstr = scopeValueAsString(sd, svf);
                    buf.append(" [" + findex + "]=(#" + fstr + ")");
                }
                buf.append(" }");
            }
            buf.br();
        }
    }

   protected String genHTMLForOopMap(OopMap map) {
      final int stack0 = VMRegImpl.getStack0().getValue();
      Formatter buf = new Formatter(genHTML);

      final class OopMapValueIterator {
         final Formatter iterate(OopMapStream oms, String type, boolean printContentReg) {
            Formatter tmpBuf = new Formatter(genHTML);
            boolean found = false;
            tmpBuf.beginTag("tr");
            tmpBuf.beginTag("td");
            tmpBuf.append(type);
            for (; ! oms.isDone(); oms.next()) {
               OopMapValue omv = oms.getCurrent();
               if (omv == null) {
                  continue;
               }
               found = true;
               VMReg vmReg = omv.getReg();
               int reg = vmReg.getValue();
               if (reg < stack0) {
                  tmpBuf.append(VMRegImpl.getRegisterName(reg));
               } else {
                  tmpBuf.append('[');
                  tmpBuf.append(Integer.toString((reg - stack0) * 4));
                  tmpBuf.append(']');
               }
               if (printContentReg) {
                  tmpBuf.append(" = ");
                  VMReg vmContentReg = omv.getContentReg();
                  int contentReg = vmContentReg.getValue();
                  if (contentReg < stack0) {
                     tmpBuf.append(VMRegImpl.getRegisterName(contentReg));
                  } else {
                     tmpBuf.append('[');
                     tmpBuf.append(Integer.toString((contentReg - stack0) * 4));
                     tmpBuf.append(']');
                  }
               }
               tmpBuf.append(spaces);
            }
            tmpBuf.endTag("td");
            tmpBuf.endTag("tr");
            return found ? tmpBuf : new Formatter(genHTML);
         }
      }

      buf.beginTable(0);

      OopMapValueIterator omvIterator = new OopMapValueIterator();
      OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.OOP_VALUE);
      buf.append(omvIterator.iterate(oms, "Oops:", false));

      oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
      buf.append(omvIterator.iterate(oms, "NarrowOops:", false));

      oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE);
      buf.append(omvIterator.iterate(oms, "Values:", false));

      oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE);
      buf.append(omvIterator.iterate(oms, "Callee saved:",  true));

      oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE);
      buf.append(omvIterator.iterate(oms, "Derived oops:", true));

      buf.endTag("table");
      return buf.toString();
   }


   protected String genOopMapInfo(NMethod nmethod, PCDesc pcDesc) {
      OopMapSet mapSet = nmethod.getOopMaps();
      if (mapSet == null || (mapSet.getSize() <= 0))
        return "";
      int pcOffset = pcDesc.getPCOffset();
      OopMap map = mapSet.findMapAtOffset(pcOffset, VM.getVM().isDebugging());
      if (map == null) {
         throw new IllegalArgumentException("no oopmap at safepoint!");
      }

      return genOopMapInfo(map);
   }

   protected String genOopMapInfo(OopMap map) {
     Formatter buf = new Formatter(genHTML);
     buf.beginTag("pre");
     buf.append("OopMap: ");
     buf.br();
     buf.append(genHTMLForOopMap(map));
     buf.endTag("pre");

     return buf.toString();
   }

   protected String locationAsString(Location loc) {
      Formatter buf = new Formatter(genHTML);
      if (loc.isIllegal()) {
         buf.append("illegal");
      } else {
         Location.Where  w  = loc.getWhere();
         Location.Type type = loc.getType();

         if (w == Location.Where.ON_STACK) {
            buf.append("stack[" + loc.getStackOffset() + "]");
         } else if (w == Location.Where.IN_REGISTER) {
            boolean isFloat = (type == Location.Type.FLOAT_IN_DBL ||
                               type == Location.Type.DBL);
            int regNum = loc.getRegisterNumber();
            VMReg vmReg = new VMReg(regNum);
            buf.append(VMRegImpl.getRegisterName(vmReg.getValue()));
         }

         buf.append(", ");
         if (type == Location.Type.NORMAL) {
            buf.append("normal");
         } else if (type == Location.Type.OOP) {
            buf.append("oop");
         } else if (type == Location.Type.NARROWOOP) {
            buf.append("narrowoop");
         } else if (type == Location.Type.INT_IN_LONG) {
            buf.append("int");
         } else if (type == Location.Type.LNG) {
            buf.append("long");
         } else if (type == Location.Type.FLOAT_IN_DBL) {
            buf.append("float");
         } else if (type == Location.Type.DBL) {
            buf.append("double");
         } else if (type == Location.Type.ADDR) {
            buf.append("address");
         } else if (type == Location.Type.INVALID) {
            buf.append("invalid");
         }
      }
      return buf.toString();
   }

   private String scopeValueAsString(ScopeDesc sd, ScopeValue sv) {
      Formatter buf = new Formatter(genHTML);
      if (sv.isConstantInt()) {
         buf.append("int ");
         ConstantIntValue intValue = (ConstantIntValue) sv;
         buf.append(Integer.toString(intValue.getValue()));
      } else if (sv.isConstantLong()) {
         buf.append("long ");
         ConstantLongValue longValue = (ConstantLongValue) sv;
         buf.append(Long.toString(longValue.getValue()));
         buf.append("L");
      } else if (sv.isConstantDouble()) {
         buf.append("double ");
         ConstantDoubleValue dblValue = (ConstantDoubleValue) sv;
         buf.append(Double.toString(dblValue.getValue()));
         buf.append("D");
      } else if (sv.isConstantOop()) {
         buf.append("oop ");
         ConstantOopReadValue oopValue = (ConstantOopReadValue) sv;
         OopHandle oopHandle = oopValue.getValue();
         if (oopHandle != null) {
            buf.append(oopHandle.toString());
         } else {
            buf.append("null");
         }
      } else if (sv.isLocation()) {
         LocationValue lvalue = (LocationValue) sv;
         Location loc = lvalue.getLocation();
         if (loc != null) {
            buf.append(locationAsString(loc));
         } else {
            buf.append("null");
         }
      } else if (sv.isObject()) {
         ObjectValue ov = (ObjectValue)sv;
         buf.append("#ScObj" + sd.getObjects().indexOf(ov));
      } else {
         buf.append("unknown scope value " + sv);
      }
      return buf.toString();
   }

   protected String genHTMLForScopeValues(ScopeDesc sd, boolean locals, List values) {
      int length = values.size();
      Formatter buf = new Formatter(genHTML);
      buf.append(locals? "locals " : "expressions ");
      for (int i = 0; i < length; i++) {
         ScopeValue sv = (ScopeValue) values.get(i);
         if (sv == null) {
            continue;
         }
         buf.append('(');
         if (locals) {
            Symbol name = sd.getMethod().getLocalVariableName(sd.getBCI(), i);
            if (name != null) {
               buf.append("'");
               buf.append(name.asString());
               buf.append('\'');
            } else {
               buf.append("[");
               buf.append(Integer.toString(i));
               buf.append(']');
            }
         } else {
            buf.append("[");
            buf.append(Integer.toString(i));
            buf.append(']');
         }

         buf.append(", ");
         buf.append(scopeValueAsString(sd, sv));
         buf.append(") ");
      }

      return buf.toString();
   }

   protected String genHTMLForLocals(ScopeDesc sd, List locals) {
      return genHTMLForScopeValues(sd, true, locals);
   }

   protected String genHTMLForExpressions(ScopeDesc sd, List expressions) {
      return genHTMLForScopeValues(sd, false, expressions);
   }

   protected String genHTMLForMonitors(ScopeDesc sd, List monitors) {
      int length = monitors.size();
      Formatter buf = new Formatter(genHTML);
      buf.append("monitors ");
      for (int i = 0; i < length; i++) {
         MonitorValue mv = (MonitorValue) monitors.get(i);
         if (mv == null) {
            continue;
         }
         buf.append("(owner = ");
         ScopeValue owner = mv.owner();
         if (owner != null) {
            buf.append(scopeValueAsString(sd, owner));
         } else {
            buf.append("null");
         }
         buf.append(", lock = ");

         Location loc = mv.basicLock();
         if (loc != null) {
            buf.append(locationAsString(loc));
         } else {
            buf.append("null");
         }
         buf.append(") ");
      }
      return buf.toString();
   }

   public String genHTML(final NMethod nmethod) {
      try {
         final Formatter buf = new Formatter(genHTML);
         buf.genHTMLPrologue(genNMethodTitle(nmethod));
         buf.h3("Method");
         buf.append(genMethodAndKlassLink(nmethod.getMethod()));

         buf.h3("Compiled Code");
         Disassembler.decode(new HTMLDisassembler(buf, nmethod), nmethod);
         buf.genHTMLEpilogue();
         return buf.toString();
      } catch (Exception exp) {
         return genHTMLErrorMessage(exp);
      }
   }

  public String genHTML(final CodeBlob blob) {
      try {
         final Formatter buf = new Formatter(genHTML);
         buf.genHTMLPrologue(genCodeBlobTitle(blob));
         buf.h3("CodeBlob");

         buf.h3("Compiled Code");
         Disassembler.decode(new HTMLDisassembler(buf, blob), blob);

         buf.genHTMLEpilogue();
         return buf.toString();
      } catch (Exception exp) {
         return genHTMLErrorMessage(exp);
      }
   }

   protected String genInterpreterCodeletTitle(InterpreterCodelet codelet) {
      Formatter buf = new Formatter(genHTML);
      buf.append("Interpreter codelet [");
      buf.append(codelet.codeBegin().toString());
      buf.append(',');
      buf.append(codelet.codeEnd().toString());
      buf.append(") - ");
      buf.append(codelet.getDescription());
      return buf.toString();
   }

   protected String genInterpreterCodeletLinkPageHref(StubQueue stubq) {
      return genBaseHref() + "interp_codelets";
   }

   public String genInterpreterCodeletLinksPage() {
      Formatter buf = new Formatter(genHTML);
      buf.genHTMLPrologue("Interpreter Codelets");
      buf.beginTag("ul");

      Interpreter interp = VM.getVM().getInterpreter();
      StubQueue code = interp.getCode();
      InterpreterCodelet stub = (InterpreterCodelet) code.getFirst();
      while (stub != null) {
         buf.beginTag("li");
         sun.jvm.hotspot.debugger.Address addr = stub.codeBegin();
         buf.link(genPCHref(addressToLong(addr)), stub.getDescription() + " @" + addr);
         buf.endTag("li");
         stub = (InterpreterCodelet) code.getNext(stub);
      }

      buf.endTag("ul");
      buf.genHTMLEpilogue();
      return buf.toString();
   }

   public String genHTML(InterpreterCodelet codelet) {
      Formatter buf = new Formatter(genHTML);
      buf.genHTMLPrologue(genInterpreterCodeletTitle(codelet));
      Interpreter interp = VM.getVM().getInterpreter();
      StubQueue stubq = interp.getCode();

      if (genHTML) {
         buf.beginTag("h3");
         buf.link(genInterpreterCodeletLinkPageHref(stubq), "View links for all codelets");
         buf.endTag("h3");
         buf.br();
      }

      Stub prev = stubq.getPrev(codelet);
      if (prev != null) {
         if (genHTML) {
            buf.beginTag("h3");
            buf.link(genPCHref(addressToLong(prev.codeBegin())), "View Previous Codelet");
            buf.endTag("h3");
            buf.br();
         } else {
            buf.h3("Previous Codelet = 0x" + Long.toHexString(addressToLong(prev.codeBegin())));
         }
      }

      buf.h3("Code");
      Disassembler.decode(new HTMLDisassembler(buf, null), null,
                          codelet.codeBegin(), codelet.codeEnd());

      Stub next = stubq.getNext(codelet);
      if (next != null) {
         if (genHTML) {
            buf.beginTag("h3");
            buf.link(genPCHref(addressToLong(next.codeBegin())), "View Next Codelet");
            buf.endTag("h3");
         } else {
            buf.h3("Next Codelet = 0x" + Long.toHexString(addressToLong(next.codeBegin())));
         }
      }

      buf.genHTMLEpilogue();
      return buf.toString();
   }

   protected String genDumpKlassesTitle(InstanceKlass[] klasses) {
      return (klasses.length == 1) ? "Create .class for this class"
                                   : "Create .class for all classes";
   }

   protected String genDumpKlassesHref(InstanceKlass[] klasses) {
      StringBuffer buf = new StringBuffer(genBaseHref());
      buf.append("jcore_multiple=");
      for (int k = 0; k < klasses.length; k++) {
         buf.append(klasses[k].getAddress().toString());
         buf.append(',');
      }
      return buf.toString();
   }

   protected String genDumpKlassesLink(InstanceKlass[] klasses) {
      if (!genHTML) return "";

      Formatter buf = new Formatter(genHTML);
      buf.link(genDumpKlassesHref(klasses), genDumpKlassesTitle(klasses));
      return buf.toString();
   }

   public String genHTMLForKlassNames(InstanceKlass[] klasses) {
      try {
         Formatter buf = new Formatter(genHTML);
         buf.genHTMLPrologue();
         buf.h3(genDumpKlassesLink(klasses));

         buf.append(genHTMLListForKlassNames(klasses));
         buf.genHTMLEpilogue();
         return buf.toString();
      } catch (Exception exp) {
         return genHTMLErrorMessage(exp);
      }
   }

   protected String genHTMLListForKlassNames(InstanceKlass[] klasses) {
      final Formatter buf = new Formatter(genHTML);
      buf.beginTable(0);
      for (int i = 0; i < klasses.length; i++) {
         InstanceKlass ik = klasses[i];
         buf.beginTag("tr");
         buf.cell(genKlassLink(ik));
         buf.endTag("tr");
      }

      buf.endTable();
      return buf.toString();
   }

   public String genHTMLForMethodNames(InstanceKlass klass) {
      try {
         Formatter buf = new Formatter(genHTML);
         buf.genHTMLPrologue();
         buf.append(genHTMLListForMethods(klass));
         buf.genHTMLEpilogue();
         return buf.toString();
      } catch (Exception exp) {
         return genHTMLErrorMessage(exp);
      }
   }

   protected String genHTMLListForMethods(InstanceKlass klass) {
      Formatter buf = new Formatter(genHTML);
      MethodArray methods = klass.getMethods();
      int numMethods = methods.length();
      if (numMethods != 0) {
         buf.h3("Methods");
         buf.beginTag("ul");
         for (int m = 0; m < numMethods; m++) {
            Method mtd = methods.at(m);
            buf.li(genMethodLink(mtd) + ";");
         }
         buf.endTag("ul");
      }
      return buf.toString();
   }

   protected String genHTMLListForInterfaces(InstanceKlass klass) {
      try {
         Formatter buf = new Formatter(genHTML);
         KlassArray interfaces = klass.getLocalInterfaces();
         int numInterfaces = interfaces.length();
         if (numInterfaces != 0) {
            buf.h3("Interfaces");
            buf.beginTag("ul");
            for (int i = 0; i < numInterfaces; i++) {
               InstanceKlass inf = (InstanceKlass) interfaces.getAt(i);
               buf.li(genKlassLink(inf));
            }
            buf.endTag("ul");
         }
         return buf.toString();
      } catch (Exception exp) {
         return genHTMLErrorMessage(exp);
      }
   }

   protected String genFieldModifierString(AccessFlags acc) {
      Formatter buf = new Formatter(genHTML);
      if (acc.isPrivate()) {
         buf.append("private ");
      } else if (acc.isProtected()) {
         buf.append("protected ");
      } else if (acc.isPublic()) {
         buf.append("public ");
      }

      if (acc.isStatic()) {
         buf.append("static ");
      }

      if (acc.isFinal()) {
         buf.append("final ");
      }
      if (acc.isVolatile()) {
         buf.append("volatile ");
      }
      if (acc.isTransient()) {
         buf.append("transient ");
      }

      // javac generated flags
      if (acc.isSynthetic()) {
         buf.append("[synthetic] ");
      }
      return buf.toString();
   }

   public String genHTMLForFieldNames(InstanceKlass klass) {
      try {
         Formatter buf = new Formatter(genHTML);
         buf.genHTMLPrologue();
         buf.append(genHTMLListForFields(klass));
         buf.genHTMLEpilogue();
         return buf.toString();
      } catch (Exception exp) {
         return genHTMLErrorMessage(exp);
      }
   }

   protected String genHTMLListForFields(InstanceKlass klass) {
      Formatter buf = new Formatter(genHTML);
      U2Array fields = klass.getFields();
      int numFields = klass.getAllFieldsCount();
      if (numFields != 0) {
         buf.h3("Fields");
         buf.beginList();
         for (int f = 0; f < numFields; f++) {
           sun.jvm.hotspot.oops.Field field = klass.getFieldByIndex(f);
           String f_name = ((NamedFieldIdentifier)field.getID()).getName();
           Symbol f_sig  = field.getSignature();
           Symbol f_genSig = field.getGenericSignature();
           AccessFlags acc = field.getAccessFlagsObj();

           buf.beginListItem();
           buf.append(genFieldModifierString(acc));
           buf.append(' ');
           Formatter sigBuf = new Formatter(genHTML);
           new SignatureConverter(f_sig, sigBuf.getBuffer()).dispatchField();
           buf.append(sigBuf.toString().replace('/', '.'));
           buf.append(' ');
           buf.append(f_name);
           buf.append(';');
           // is it generic?
           if (f_genSig != null) {
              buf.append(" [signature ");
              buf.append(escapeHTMLSpecialChars(f_genSig.asString()));
              buf.append("] ");
           }
           buf.append(" (offset = " + field.getOffset() + ")");
           buf.endListItem();
         }
         buf.endList();
      }
      return buf.toString();
   }

   protected String genKlassHierarchyHref(InstanceKlass klass) {
      return genBaseHref() + "hierarchy=" + klass.getAddress();
   }

   protected String genKlassHierarchyTitle(InstanceKlass klass) {
      Formatter buf = new Formatter(genHTML);
      buf.append("Class Hierarchy of ");
      buf.append(genKlassTitle(klass));
      return buf.toString();
   }

   protected String genKlassHierarchyLink(InstanceKlass klass) {
      Formatter buf = new Formatter(genHTML);
      buf.link(genKlassHierarchyHref(klass), genKlassHierarchyTitle(klass));
      return buf.toString();
   }

   protected String genHTMLListForSubKlasses(InstanceKlass klass) {
      Formatter buf = new Formatter(genHTML);
      Klass subklass = klass.getSubklassKlass();
      if (subklass != null) {
         buf.beginList();
         while (subklass != null) {
            if (subklass instanceof InstanceKlass) {
               buf.li(genKlassLink((InstanceKlass)subklass));
            }
            subklass = subklass.getNextSiblingKlass();
         }
         buf.endList();
      }
      return buf.toString();
   }

   public String genHTMLForKlassHierarchy(InstanceKlass klass) {
      Formatter buf = new Formatter(genHTML);
      buf.genHTMLPrologue(genKlassHierarchyTitle(klass));


      buf.beginTag("pre");
      buf.append(genKlassLink(klass));
      buf.br();
      StringBuffer tabs = new StringBuffer(tab);
      InstanceKlass superKlass = klass;
      while ( (superKlass = (InstanceKlass) superKlass.getSuper()) != null ) {
         buf.append(tabs);
         buf.append(genKlassLink(superKlass));
         tabs.append(tab);
         buf.br();
      }
      buf.endTag("pre");

      // generate subklass list
      Klass subklass = klass.getSubklassKlass();
      if (subklass != null) {
         buf.h3("Direct Subclasses");
         buf.append(genHTMLListForSubKlasses(klass));
      }

      buf.genHTMLEpilogue();
      return buf.toString();
   }

   protected String genDumpKlassHref(InstanceKlass klass) {
      return genBaseHref() + "jcore=" + klass.getAddress();
   }

   protected String genDumpKlassLink(InstanceKlass klass) {
      if (!genHTML) return "";

      Formatter buf = new Formatter(genHTML);
      buf.link(genDumpKlassHref(klass), "Create .class File");
      return buf.toString();
   }

   public String genHTML(InstanceKlass klass) {
      Formatter buf = new Formatter(genHTML);
      buf.genHTMLPrologue(genKlassTitle(klass));
      InstanceKlass superKlass = (InstanceKlass) klass.getSuper();

      if (genHTML) {
          // super class tree and subclass list
          buf.beginTag("h3");
          buf.link(genKlassHierarchyHref(klass), "View Class Hierarchy");
          buf.endTag("h3");
      }

      // jcore - create .class link
      buf.h3(genDumpKlassLink(klass));

      // super class
      if (superKlass != null) {
         buf.h3("Super Class");
         buf.append(genKlassLink(superKlass));
      }

      // interfaces
      buf.append(genHTMLListForInterfaces(klass));

      // fields
      buf.append(genHTMLListForFields(klass));

      // methods
      buf.append(genHTMLListForMethods(klass));

      // constant pool link
      buf.h3("Constant Pool");
      buf.append(genConstantPoolLink(klass.getConstants()));

      buf.genHTMLEpilogue();
      return buf.toString();
   }

   protected sun.jvm.hotspot.debugger.Address parseAddress(String address) {
      VM vm = VM.getVM();
      sun.jvm.hotspot.debugger.Address addr = vm.getDebugger().parseAddress(address);
      return addr;
   }

   protected long addressToLong(sun.jvm.hotspot.debugger.Address addr) {
      return VM.getVM().getDebugger().getAddressValue(addr);
   }

   protected sun.jvm.hotspot.debugger.Address longToAddress(long addr) {
      return parseAddress("0x" + Long.toHexString(addr));
   }

   protected Oop getOopAtAddress(sun.jvm.hotspot.debugger.Address addr) {
      OopHandle oopHandle = addr.addOffsetToAsOopHandle(0);
      return VM.getVM().getObjectHeap().newOop(oopHandle);
   }

   protected Oop getOopAtAddress(String address) {
      sun.jvm.hotspot.debugger.Address addr = parseAddress(address);
      return getOopAtAddress(addr);
   }

   protected Klass getKlassAtAddress(String address) {
      sun.jvm.hotspot.debugger.Address addr = parseAddress(address);
      return (Klass)Metadata.instantiateWrapperFor(addr);
   }

   protected Method getMethodAtAddress(String address) {
      sun.jvm.hotspot.debugger.Address addr = parseAddress(address);
      return (Method)Metadata.instantiateWrapperFor(addr);
   }

   protected ConstantPool getConstantPoolAtAddress(String address) {
      sun.jvm.hotspot.debugger.Address addr = parseAddress(address);
      return (ConstantPool) Metadata.instantiateWrapperFor(addr);
   }

   private void dumpKlass(InstanceKlass kls) throws IOException {
      String klassName = kls.getName().asString();
      klassName = klassName.replace('/', File.separatorChar);
      int index = klassName.lastIndexOf(File.separatorChar);
      File dir = null;
      if (index != -1) {
        String dirName = klassName.substring(0, index);
        dir =  new File(DUMP_KLASS_OUTPUT_DIR,  dirName);
      } else {
        dir = new File(DUMP_KLASS_OUTPUT_DIR);
      }

      dir.mkdirs();
      File f = new File(dir, klassName.substring(klassName.lastIndexOf(File.separatorChar) + 1)
                              + ".class");
      f.createNewFile();
      FileOutputStream fis = new FileOutputStream(f);
      ClassWriter cw = new ClassWriter(kls, fis);
      cw.write();
   }

   public String genDumpKlass(InstanceKlass kls) {
      try {
         dumpKlass(kls);
         Formatter buf = new Formatter(genHTML);
         buf.genHTMLPrologue(genKlassTitle(kls));
         buf.append(".class created for ");
         buf.append(genKlassLink(kls));
         buf.genHTMLEpilogue();
         return buf.toString();
      } catch(IOException exp) {
         return genHTMLErrorMessage(exp);
      }
   }

   protected String genJavaStackTraceTitle(JavaThread thread) {
      Formatter buf = new Formatter(genHTML);
      buf.append("Java Stack Trace for ");
      buf.append(thread.getThreadName());
      return buf.toString();
   }

   public String genHTMLForJavaStackTrace(JavaThread thread) {
      Formatter buf = new Formatter(genHTML);
      buf.genHTMLPrologue(genJavaStackTraceTitle(thread));

      buf.append("Thread state = ");
      buf.append(thread.getThreadState().toString());
      buf.br();
      buf.beginTag("pre");
      for (JavaVFrame vf = thread.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
         Method method = vf.getMethod();
         buf.append(" - ");
         buf.append(genMethodLink(method));
         buf.append(" @bci = " + vf.getBCI());

         int lineNumber = method.getLineNumberFromBCI(vf.getBCI());
         if (lineNumber != -1) {
            buf.append(", line = ");
            buf.append(lineNumber);
         }

         sun.jvm.hotspot.debugger.Address pc = vf.getFrame().getPC();
         if (pc != null) {
            buf.append(", pc = ");
            buf.link(genPCHref(addressToLong(pc)), pc.toString());
         }

         if (vf.isCompiledFrame()) {
            buf.append(" (Compiled");
         }
         else if (vf.isInterpretedFrame()) {
            buf.append(" (Interpreted");
         }

         if (vf.mayBeImpreciseDbg()) {
            buf.append("; information may be imprecise");
         }
         buf.append(")");
         buf.br();
      }

      buf.endTag("pre");
      buf.genHTMLEpilogue();
      return buf.toString();
   }

   public String genHTMLForHyperlink(String href) {
      if (href.startsWith("klass=")) {
         href = href.substring(href.indexOf('=') + 1);
         Klass k = getKlassAtAddress(href);
         if (Assert.ASSERTS_ENABLED) {
            Assert.that(k instanceof InstanceKlass, "class= href with improper InstanceKlass!");
         }
         return genHTML((InstanceKlass) k);
      } else if (href.startsWith("method=")) {
         href = href.substring(href.indexOf('=') + 1);
         Method obj = getMethodAtAddress(href);
         if (Assert.ASSERTS_ENABLED) {
            Assert.that(obj instanceof Method, "method= href with improper Method!");
         }
         return genHTML(obj);
      } else if (href.startsWith("nmethod=")) {
         String addr = href.substring(href.indexOf('=') + 1);
         Object obj = VMObjectFactory.newObject(NMethod.class, parseAddress(addr));
         if (Assert.ASSERTS_ENABLED) {
            Assert.that(obj instanceof NMethod, "nmethod= href with improper NMethod!");
         }
         return genHTML((NMethod) obj);
      } else if (href.startsWith("pc=")) {
         String address = href.substring(href.indexOf('=') + 1);
         return genHTML(parseAddress(address));
      } else if (href.startsWith("pc_multiple=")) {
         int indexOfComma = href.indexOf(',');
         if (indexOfComma == -1) {
            String firstPC = href.substring(href.indexOf('=') + 1);
            return genHTMLForRawDisassembly(parseAddress(firstPC), null);
         } else {
            String firstPC = href.substring(href.indexOf('=') + 1, indexOfComma);
            return genHTMLForRawDisassembly(parseAddress(firstPC), href.substring(indexOfComma + 1));
         }
      } else if (href.startsWith("interp_codelets")) {
         return genInterpreterCodeletLinksPage();
      } else if (href.startsWith("hierarchy=")) {
         href = href.substring(href.indexOf('=') + 1);
         Klass obj = getKlassAtAddress(href);
         if (Assert.ASSERTS_ENABLED) {
            Assert.that(obj instanceof InstanceKlass, "class= href with improper InstanceKlass!");
         }
         return genHTMLForKlassHierarchy((InstanceKlass) obj);
      } else if (href.startsWith("cpool=")) {
         href = href.substring(href.indexOf('=') + 1);
         ConstantPool obj = getConstantPoolAtAddress(href);
         if (Assert.ASSERTS_ENABLED) {
            Assert.that(obj instanceof ConstantPool, "cpool= href with improper ConstantPool!");
         }
         return genHTML(obj);
      } else if (href.startsWith("jcore=")) {
         href = href.substring(href.indexOf('=') + 1);
         Klass obj = getKlassAtAddress(href);
         if (Assert.ASSERTS_ENABLED) {
            Assert.that(obj instanceof InstanceKlass, "jcore= href with improper InstanceKlass!");
         }
         return genDumpKlass((InstanceKlass) obj);
      } else if (href.startsWith("jcore_multiple=")) {
         href = href.substring(href.indexOf('=') + 1);
         Formatter buf = new Formatter(genHTML);
         buf.genHTMLPrologue();
         StringTokenizer st = new StringTokenizer(href, ",");
         while (st.hasMoreTokens()) {
            Klass obj = getKlassAtAddress(st.nextToken());
            if (Assert.ASSERTS_ENABLED) {
               Assert.that(obj instanceof InstanceKlass, "jcore_multiple= href with improper InstanceKlass!");
            }

            InstanceKlass kls = (InstanceKlass) obj;
            try {
               dumpKlass(kls);
               buf.append(".class created for ");
               buf.append(genKlassLink(kls));
            } catch(Exception exp) {
               buf.bold("can't .class for " +
                        genKlassTitle(kls) +
                        " : " +
                        exp.getMessage());
            }
            buf.br();
         }

         buf.genHTMLEpilogue();
         return buf.toString();
      } else {
         if (Assert.ASSERTS_ENABLED) {
            Assert.that(false, "unknown href link!");
         }
         return null;
      }
   }
}
