alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (sa.js)

This example Java source code file (sa.js) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

c2iadapter, compiled, cpu, debuggerthread, defnewgeneration, frame, interpreted, lp64, object, osradapter, tenuredgeneration, uncommontrapblob, usage, visitorclass

The sa.js Java example source code

/*
 * Copyright (c) 2004, 2013, 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.
 *  
 */

// shorter names for SA packages


// SA package name abbreviations are kept in 'sapkg' object
// to avoid global namespace pollution
var sapkg = new Object();

sapkg.hotspot = Packages.sun.jvm.hotspot;
sapkg.asm = sapkg.hotspot.asm;
sapkg.c1 = sapkg.hotspot.c1;
sapkg.code = sapkg.hotspot.code;
sapkg.compiler = sapkg.hotspot.compiler;

// 'debugger' is a JavaScript keyword, but ES5 relaxes the
// restriction of using keywords as property name
sapkg.debugger = sapkg.hotspot.debugger;

sapkg.interpreter = sapkg.hotspot.interpreter;
sapkg.jdi = sapkg.hotspot.jdi;
sapkg.memory = sapkg.hotspot.memory;
sapkg.oops = sapkg.hotspot.oops;
sapkg.runtime = sapkg.hotspot.runtime;
sapkg.tools = sapkg.hotspot.tools;
sapkg.types = sapkg.hotspot.types;
sapkg.ui = sapkg.hotspot.ui;
sapkg.utilities = sapkg.hotspot.utilities;

// SA singletons are kept in 'sa' object
var sa = new Object();
sa.vm = sapkg.runtime.VM.getVM();
sa.dbg = sa.vm.getDebugger();
sa.cdbg = sa.dbg.CDebugger;
sa.heap = sa.vm.universe.heap();
sa.systemDictionary = sa.vm.systemDictionary;
sa.sysDict = sa.systemDictionary;
sa.symbolTable = sa.vm.symbolTable;
sa.symTbl = sa.symbolTable;
sa.threads = sa.vm.threads;
sa.interpreter = sa.vm.interpreter;
sa.typedb = sa.vm.typeDataBase;
sa.codeCache = sa.vm.codeCache;
// 'objHeap' is different from 'heap'!. 
// This is SA's Oop factory and heap-walker
sa.objHeap = sa.vm.objectHeap;

// few useful global variables
var OS = sa.vm.OS;
var CPU = sa.vm.CPU;
var LP64 = sa.vm.LP64;
var isClient = sa.vm.clientCompiler;
var isServer = sa.vm.serverCompiler;
var isCore = sa.vm.isCore();
var addressSize = sa.vm.addressSize;
var oopSize = sa.vm.oopSize;

// this "main" function is called immediately
// after loading this script file
function main(globals, jvmarg) {
  // wrap a sun.jvm.hotspot.utilities.soql.ScriptObject
  // object so that the properties of it can be accessed
  // in natural object.field syntax.
  function wrapScriptObject(so) {
    function unwrapScriptObject(wso) {
      var objType = typeof(wso);
      if ((objType == 'object' ||
           objType == 'function')
          && "__wrapped__" in wso) {
        return wso.__wrapped__;
      } else {
        return wso;
      }
    }

    function prepareArgsArray(array) {
      var args = new Array(array.length);
      for (var a = 0; a < array.length; a++) {
        var elem = array[a];
        elem = unwrapScriptObject(elem);
        if (typeof(elem) == 'function') {
          args[a] = new sapkg.utilities.soql.Callable() {
            call: function(myargs) {
              var tmp = new Array(myargs.length);
              for (var i = 0; i < myargs.length; i++) {
                tmp[i] = wrapScriptObject(myargs[i]);
              }
              return elem.apply(this, tmp);
            }
          }
        } else {
          args[a] = elem;
        }
      }
      return args;
    }

    // Handle __has__ specially to avoid metacircularity problems
    // when called from __get__.
    // Calling
    //   this.__has__(name)
    // will in turn call
    //   this.__call__('__has__', name)
    // which is not handled below
    function __has__(name) {
      if (typeof(name) == 'number') {
        return so["has(int)"](name);
      } else {
        if (name == '__wrapped__') {
          return true;
        } else if (so["has(java.lang.String)"](name)) {
          return true;
        } else if (name.equals('toString')) {
          return true;
        } else {
          return false;
        }
      }
    }

    if (so instanceof sapkg.utilities.soql.ScriptObject) {
      return new JSAdapter() {
        __getIds__: function() {
          return so.getIds();
        },
  
        __has__ : __has__,
  
        __delete__ : function(name) {
          if (typeof(name) == 'number') {
            return so["delete(int)"](name);
          } else {
            return so["delete(java.lang.String)"](name);
          }
        },
  
        __get__ : function(name) {
	      // don't call this.__has__(name); see comments above function __has__
          if (! __has__.call(this, name)) {
            return undefined;
          }
          if (typeof(name) == 'number') {
            return wrapScriptObject(so["get(int)"](name));
          } else {
            if (name == '__wrapped__') {
              return so;
            } else {
              var value = so["get(java.lang.String)"](name);
              if (value instanceof sapkg.utilities.soql.Callable) {
                return function() {
                  var args = prepareArgsArray(arguments);
                  var r;
                  try {
                    r = value.call(Java.to(args, 'java.lang.Object[]'));
                  } catch (e) {
                    println("call to " + name + " failed!");
                    throw e;
                  }
                  return wrapScriptObject(r);
                }
              } else if (name == 'toString') {
                return function() { 
                  return so.toString();
                }
              } else {
                return wrapScriptObject(value);
              }
            }
          }
        }
      };
    } else {
      return so;
    }
  }

  // set "jvm" global variable that wraps a 
  // sun.jvm.hotspot.utilities.soql.JSJavaVM instance
  if (jvmarg != null) {
    jvm = wrapScriptObject(jvmarg);
    // expose "heap" global variable
    heap = jvm.heap;
  }

  // expose all "function" type properties of
  // sun.jvm.hotspot.utilitites.soql.JSJavaScriptEngine
  // as global functions here.
  globals = wrapScriptObject(globals);
  for (var prop in globals) {    
    if (typeof(globals[prop]) == 'function') {
      this[prop] = globals[prop];
    }    
  }

  // define "writeln" and "write" if not defined
  if (typeof(println) == 'undefined') {
    println = function (str) {
      java.lang.System.out.println(String(str));
    }
  }

  if (typeof(print) == 'undefined') {
    print = function (str) {
      java.lang.System.out.print(String(str));
    }
  }

  if (typeof(writeln) == 'undefined') {
    writeln = println;
  }

  if (typeof(write) == 'undefined') {
    write = print;
  }

  // "registerCommand" function is defined if we
  // are running as part of "CLHSDB" tool. CLHSDB
  // tool exposes Unix-style commands. 

  // if "registerCommand" function is defined
  // then register few global functions as "commands".
  if (typeof(registerCommand) == 'function') {
    this.jclass = function(name) {
      if (typeof(name) == "string") {
         var clazz = sapkg.utilities.SystemDictionaryHelper.findInstanceKlass(name);
         if (clazz) {
             writeln(clazz.getName().asString() + " @" + clazz.getAddress().toString());
         } else {
             writeln("class not found: " + name);
         } 
      } else {
         writeln("Usage: class name");
      }
    }
    registerCommand("class", "class name", "jclass");

    this.jclasses = function() {
      forEachKlass(function (clazz) {
        writeln(clazz.getName().asString() + " @" + clazz.getAddress().toString()); 
      });
    }
    registerCommand("classes", "classes", "jclasses");

    this.dclass = function(clazz, dir) {
      if (!clazz) {
         writeln("Usage: dumpclass { address | name } [ directory ]");
      } else {
         if (!dir) { dir = "."; }
         dumpClass(clazz, dir);
      }
    }
    registerCommand("dumpclass", "dumpclass { address | name } [ directory ]", "dclass");
    registerCommand("dumpheap", "dumpheap [ file ]", "dumpHeap");

    this.jseval = function(str) {
      if (!str) {
         writeln("Usage: jseval script");
      } else {
         var res = eval(str);
         if (res) { writeln(res); }
      }
    }
    registerCommand("jseval", "jseval script", "jseval");

    this.jsload = function(file) {
      if (!file) {
         writeln("Usage: jsload file");
      } else {
         load(file);
      }
    }
    registerCommand("jsload", "jsload file", "jsload");

    this.printMem = function(addr, len) {
      if (!addr) {
         writeln("Usage: mem [ length ]");
      } else {
         mem(addr, len);
      }
    }
    registerCommand("mem", "mem address [ length ]", "printMem");

    this.sysProps = function() {
      for (var i in jvm.sysProps) {
         writeln(i + ' = ' + jvm.sysProps[i]);
      }
    }
    registerCommand("sysprops", "sysprops", "sysProps");

    this.printWhatis = function(addr) {
      if (!addr) {
         writeln("Usage: whatis address");
      } else {
         writeln(whatis(addr));
      }
    }
    registerCommand("whatis", "whatis address", "printWhatis");
  }  
}

// debugger functionality

// string-to-Address
function str2addr(str) {
   return sa.dbg.parseAddress(str);
}

// number-to-Address
if (addressSize == 4) {
   eval("function num2addr(num) { \
            return str2addr('0x' + java.lang.Integer.toHexString(0xffffffff & num)); \
         }");
} else {
   eval("function num2addr(num) { \
            return str2addr('0x' + java.lang.Long.toHexString(num));  \
         }");
}

// generic any-type-to-Address
// use this convenience function to accept address in any
// format -- number, string or an Address instance.
function any2addr(addr) {
   var type = typeof(addr);
   if (type == 'number') {
      return num2addr(addr);
   } else if (type == 'string') {         
      return str2addr(addr);
   } else {
      return addr;
   }
}

// Address-to-string
function addr2str(addr) {
   if (addr == null) {
      return (addressSize == 4)? '0x00000000' : '0x0000000000000000';
   } else {
      return addr + '';
   }
}

// Address-to-number
function addr2num(addr) {
   return sa.dbg.getAddressValue(addr);
}

// symbol-to-Address
function sym2addr(dso, sym) {
   return sa.dbg.lookup(dso, sym);
}

// returns the ClosestSymbol or null
function closestSymbolFor(addr) {
   if (sa.cdbg == null) {
      // no CDebugger support, return null
      return null;
   } else {
      var dso = sa.cdbg.loadObjectContainingPC(addr);
      if (dso != null) {
         return dso.closestSymbolToPC(addr);
      } else {
         return null;
      }
   }
}

// Address-to-symbol
// returns nearest symbol as string if found
// else returns address as string
function addr2sym(addr) {
    var sym = closestSymbolFor(addr);
    if (sym != null)  {
       return sym.name + '+' + sym.offset;
    } else {
       return addr2str(addr);
    }
}

// read 'num' words at 'addr' and return an array as result.
// returns Java long[] type result and not a JavaScript array.
function readWordsAt(addr, num) {
   addr = any2addr(addr);
   var res = java.lang.reflect.Array.newInstance(java.lang.Long.TYPE, num);
   var i;
   for (i = 0; i < num; i++) {
      res[i] = addr2num(addr.getAddressAt(i * addressSize));
   }
   return res;
}

// read the 'C' string at 'addr'
function readCStrAt(addr) {
   addr = any2addr(addr);
   return sapkg.utilities.CStringUtilities.getString(addr);
}

// read the length of the 'C' string at 'addr'
function readCStrLen(addr) {
   addr = any2addr(addr);
   return sapkg.utilities.CStringUtilities.getStringLength(addr);
}

// iterate through ThreadList of CDebugger
function forEachThread(callback) {
   if (sa.cdbg == null) {
      // no CDebugger support
      return;
   } else {
      var itr = sa.cdbg.threadList.iterator();
      while (itr.hasNext()) {
         if (callback(itr.next()) == false) return;
      }
   }
}

// read register set of a ThreadProxy as name-value pairs
function readRegs(threadProxy) {
   var ctx = threadProxy.context;
   var num = ctx.numRegisters;
   var res = new Object();
   var i;
   for (i = 0; i < num; i++) {
      res[ctx.getRegisterName(i)]= addr2str(ctx.getRegisterAsAddress(i));
   }
   return res;
}

// print register set for a given ThreaProxy
function regs(threadProxy) {
   var res = readRegs(threadProxy);
   for (i in res) {
      writeln(i, '=', res[i]);
   }
}

// iterate through each CFrame of a given ThreadProxy
function forEachCFrame(threadProxy, callback) {   
   if (sa.cdbg == null) {
      // no CDebugger support
      return;
   } else {
      var cframe = sa.cdbg.topFrameForThread(threadProxy);
      while (cframe != null) {
         if (callback(cframe) == false) return;
         cframe = cframe.sender();
      }
   }
}

// iterate through list of load objects (DLLs, DSOs)
function forEachLoadObject(callback) {
   if (sa.cdbg == null) {
      // no CDebugger support
      return;
   } else {
      var itr = sa.cdbg.loadObjectList.iterator();
      while (itr.hasNext()) {
         if (callback(itr.next()) == false) return;
      }
   }
}

// print 'num' words at 'addr'
function mem(addr, num) {
   if (num == undefined) {
      num = 1;
   }
   addr = any2addr(addr);   
   var i;
   for (i = 0; i < num; i++) {
      var value = addr.getAddressAt(0);      
      writeln(addr2sym(addr) + ':', addr2str(value)); 
      addr = addr.addOffsetTo(addressSize);      
   }
   writeln();
}

// System dictionary functions

// find InstanceKlass by name
function findInstanceKlass(name) {
   return sapkg.utilities.SystemDictionaryHelper.findInstanceKlass(name);
}

// get Java system loader (i.e., application launcher loader)
function systemLoader() {
   return sa.sysDict.javaSystemLoader();
}

// iterate system dictionary for each 'Klass' 
function forEachKlass(callback) {
   var VisitorClass = sapkg.memory.SystemDictionary.ClassVisitor;
   var visitor = new VisitorClass() { visit: callback };
   sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary.ClassVisitor)"](visitor);
}

// iterate system dictionary for each 'Klass' and initiating loader
function forEachKlassAndLoader(callback) {
   var VisitorClass = sapkg.memory.SystemDictionary.ClassAndLoaderVisitor;
   var visitor = new VisitorClass() { visit: callback };
   sa.sysDict["classesDo(sun.jvm.hotspot.memory.SystemDictionary.ClassAndLoaderVisitor)"](visitor);
}

// iterate system dictionary for each primitive array klass
function forEachPrimArrayKlass(callback) {
   var VisitorClass = sapkg.memory.SystemDictionary.ClassAndLoaderVisitor;
   sa.sysDict.primArrayClassesDo(new VisitorClass() { visit: callback });
}

// 'oop' to higher-level java object wrapper in which for(i in o) 
// works by iterating java level fields and javaobject.javafield
// syntax works.
function oop2obj(oop) {
   return object(addr2str(oop.handle));
}

// higher level java object wrapper to oop
function obj2oop(obj) {
   return addr2oop(str2addr(address(obj)));
}

// Java heap iteration

// iterates Java heap for each Oop
function forEachOop(callback) {
   function empty() { }
   sa.objHeap.iterate(new sapkg.oops.HeapVisitor() {
       prologue: empty,
       doObj: callback,
       epilogue: empty
   });
}

// iterates Java heap for each Oop of given 'klass'.
// 'includeSubtypes' tells whether to include objects 
// of subtypes of 'klass' or not
function forEachOopOfKlass(callback, klass, includeSubtypes) {
   if (klass == undefined) {
       klass = findInstanceKlass("java.lang.Object");
   }

   if (includeSubtypes == undefined) {
      includeSubtypes = true;
   }

   function empty() { }
   sa.objHeap.iterateObjectsOfKlass(
        new sapkg.oops.HeapVisitor() {
            prologue: empty,
            doObj: callback,
            epilogue: empty
        },
        klass, includeSubtypes);
}

// Java thread

// iterates each Thread
function forEachJavaThread(callback) {
   var threads = sa.threads;
   var thread = threads.first();
   while (thread != null) {
      if (callback(thread) == false) return;
      thread = thread.next();
   }  
}

// iterate Frames of a given thread
function forEachFrame(javaThread, callback) {
   var fr = javaThread.getLastFrameDbg();
   while (fr != null) { 
     if (callback(fr) == false) return;
     fr = fr.sender();
   }
}

// iterate JavaVFrames of a given JavaThread
function forEachVFrame(javaThread, callback) {
   var vfr = javaThread.getLastJavaVFrameDbg();
   while (vfr != null) {
      if (callback(vfr) == false) return;
      vfr = vfr.javaSender();
   }
}

function printStackTrace(javaThread) {
   write("Thread ");
   javaThread.printThreadIDOn(java.lang.System.out);
   writeln();
   forEachVFrame(javaThread, function (vf) {
      var method = vf.method;
      write(' - ', method.externalNameAndSignature(), '@bci =', vf.getBCI());
      var line = method.getLineNumberFromBCI(vf.getBCI());
      if (line != -1) { write(', line=', line); }
      if (vf.isCompiledFrame()) { write(" (Compiled Frame)"); }
      if (vf.isInterpretedFrame()) { write(" (Interpreted Frame)"); }
      writeln();
   });
   writeln();
   writeln();
}

// print Java stack trace for all threads
function where(javaThread) {
   if (javaThread == undefined) {
      forEachJavaThread(function (jt) { printStackTrace(jt); });
   } else {
      printStackTrace(javaThread);
   }
}

// vmStructs access -- type database functions

// find a VM type
function findVMType(typeName) {
   return sa.typedb.lookupType(typeName);
}

// iterate VM types
function forEachVMType(callback) {
   var itr = sa.typedb.types;
   while (itr.hasNext()) {
      if (callback(itr.next()) == false) return;
   }
}

// find VM int constant
function findVMIntConst(name) {
   return sa.typedb.lookupIntConstant(name);
}

// find VM long constant
function findVMLongConst(name) {
   return sa.typedb.lookupLongConstant(name);
}

// iterate VM int constants
function forEachVMIntConst(callback) {
   var itr = sa.typedb.intConstants;
   while (itr.hasNext()) {
      if (callback(itr.next()) == false) return;
   } 
}

// iterate VM long constants
function forEachVMLongConst(callback) {
   var itr = sa.typedb.longConstants;
   while (itr.hasNext()) {
      if (callback(itr.next()) == false) return;
   } 
}

// returns VM Type at address
function vmTypeof(addr) {
   addr = any2addr(addr);
   return sa.typedb.guessTypeForAddress(addr);
}

// does the given 'addr' points to an object of given 'type'?
// OR any valid Type at all (if type is undefined)
function isOfVMType(addr, type) {
   addr = any2addr(addr);
   if (type == undefined) {
      return vmTypeof(addr) != null;
   } else {
      if (typeof(type) == 'string') {
         type = findVMType(type);
      } 
      return sa.typedb.addressTypeIsEqualToType(addr, type);
   }
}

// reads static field value
function readVMStaticField(field) {
   var type = field.type;
   if (type.isCIntegerType() || type.isJavaPrimitiveType()) {
      return field.value;
   } else if (type.isPointerType()) {
      return field.address;
   } else if (type.isOopType()) {
      return field.oopHandle;      
   } else {
      return field.staticFieldAddress;
   }
}

// reads given instance field of VM object at 'addr'
function readVMInstanceField(field, addr) {
   var type = field.type;
   if (type.isCIntegerType() || type.isJavaPrimitiveType()) {
      return field.getValue(addr);
   } else if (type.isPointerType()) {
      return field.getAddress(addr);
   } else if (type.isOopType()) {
      return field.getOopHandle(addr);
   } else {
      return addr.addOffsetTo(field.offset);
   }
}

// returns name-value of pairs of VM type at given address.
// If address is unspecified, reads static fields as name-value pairs.
function readVMType(type, addr) {
   if (typeof(type) == 'string') {
      type = findVMType(type);
   }
   if (addr != undefined) {
      addr = any2addr(addr);
   }

   var result = new Object();
   var staticOnly = (addr == undefined);
   while (type != null) {
      var itr = type.fields;
      while (itr.hasNext()) {
         var field = itr.next();
         var isStatic = field.isStatic();
         if (staticOnly && isStatic) {
            result[field.name] = readVMStaticField(field);
         } else if (!staticOnly && !isStatic) {
            result[field.name] = readVMInstanceField(field, addr);
         }
      }
      type = type.superclass;
   } 
   return result;
}

function printVMType(type, addr) {
   if (typeof(type) == 'string') {
      type = findVMType(type);
   }
   var obj = readVMType(type, addr);
   while (type != null) {
      var itr = type.fields;
      while (itr.hasNext()) {
         var field = itr.next();
         var name = field.name;
         var value = obj[name];
         if (value != undefined) {
            writeln(field.type.name, type.name + '::' + name, '=', value);
         }
      }
      type = type.superclass;  
   }
}

// define readXXX and printXXX functions for each VM struct/class Type
tmp = new Object();
tmp.itr = sa.typedb.types;
while (tmp.itr.hasNext()) {
   tmp.type = tmp.itr.next();
   tmp.name = tmp.type.name;
   if (tmp.type.isPointerType() || tmp.type.isOopType() ||
      tmp.type.isCIntegerType() || tmp.type.isJavaPrimitiveType() ||
      tmp.name.equals('address') ||
      tmp.name.equals("<opaque>")) {
         // ignore;
         continue;
   } else {
      // some type names have ':', '<', '>', '*', ' '. replace to make it as a
      // JavaScript identifier
      tmp.name = ("" + tmp.name).replace(/[:<>* ]/g, '_');
      eval("function read" + tmp.name + "(addr) {" +
           "   return readVMType('" + tmp.name + "', addr);}"); 
      eval("function print" + tmp.name + "(addr) {" + 
           "   printVMType('" + tmp.name + "', addr); }");

      /* FIXME: do we need this?
      if (typeof(registerCommand) != 'undefined') {
          var name = "print" + tmp.name;
          registerCommand(name, name + " [address]", name);
      }
      */
   }
}
//clean-up the temporary
delete tmp;

// VMObject factory

// VM type to SA class map
var  vmType2Class = new Object();

// This is *not* exhaustive. Add more if needed.
// code blobs
vmType2Class["BufferBlob"] = sapkg.code.BufferBlob;
vmType2Class["nmethod"] = sapkg.code.NMethod;
vmType2Class["RuntimeStub"] = sapkg.code.RuntimeStub;
vmType2Class["SafepointBlob"] = sapkg.code.SafepointBlob;
vmType2Class["C2IAdapter"] = sapkg.code.C2IAdapter;
vmType2Class["DeoptimizationBlob"] = sapkg.code.DeoptimizationBlob;
vmType2Class["ExceptionBlob"] = sapkg.code.ExceptionBlob;
vmType2Class["I2CAdapter"] = sapkg.code.I2CAdapter;
vmType2Class["OSRAdapter"] = sapkg.code.OSRAdapter;
vmType2Class["UncommonTrapBlob"] = sapkg.code.UncommonTrapBlob;
vmType2Class["PCDesc"] = sapkg.code.PCDesc;

// interpreter
vmType2Class["InterpreterCodelet"] = sapkg.interpreter.InterpreterCodelet;

// Java Threads
vmType2Class["JavaThread"] = sapkg.runtime.JavaThread;
vmType2Class["CompilerThread"] = sapkg.runtime.CompilerThread;
vmType2Class["SurrogateLockerThread"] = sapkg.runtime.JavaThread;
vmType2Class["DebuggerThread"] = sapkg.runtime.DebuggerThread;

// gc
vmType2Class["GenCollectedHeap"] = sapkg.memory.GenCollectedHeap;
vmType2Class["DefNewGeneration"] = sapkg.memory.DefNewGeneration;
vmType2Class["TenuredGeneration"] = sapkg.memory.TenuredGeneration;

// generic VMObject factory for a given address
// This is equivalent to VirtualConstructor.
function newVMObject(addr) {
   addr = any2addr(addr);
   var result = null;
   forEachVMType(function (type) {
                    if (isOfVMType(addr, type)) {
                       var clazz = vmType2Class[type.name];
                       if (clazz != undefined) {
                          result = new clazz(addr);
                       }
                       return false;
                    } else {
                       return true;
                    }
                 });
   return result;
}

function vmobj2addr(vmobj) {
   return vmobj.address;
}

function addr2vmobj(addr) {
   return newVMObject(addr);
}     

// Miscellaneous utilities

// returns PointerLocation that describes the given pointer
function findPtr(addr) {
   addr = any2addr(addr);
   return sapkg.utilities.PointerFinder.find(addr);
}

// is given address a valid Oop?
function isOop(addr) {
   addr = any2addr(addr);
   var oopHandle = addr.addOffsetToAsOopHandle(0);
   return sapkg.utilities.RobustOopDeterminator.oopLooksValid(oopHandle);
}

// returns description of given pointer as a String
function whatis(addr) {
   addr = any2addr(addr);
   var ptrLoc = findPtr(addr);
   if (ptrLoc.isUnknown()) {
      var vmType = vmTypeof(addr);
      if (vmType != null) {
         return "pointer to " + vmType.name;
      } else {
         var sym = closestSymbolFor(addr);
         if (sym != null) {
            return sym.name + '+' + sym.offset;
         } else {
            return ptrLoc.toString();
         }
      }
   } else {
      return ptrLoc.toString();
   }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java sa.js source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.