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

Java example source code file (ObjectReferenceImpl.java)

This example Java source code file (ObjectReferenceImpl.java) 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

arraylist, classnotloadedexception, incompatiblethreadstateexception, invalidtypeexception, iterator, javathread, javavframe, jdi, list, map, monitorinfo, objectreferenceimpl, oop, unsupportedoperationexception, util, value

The ObjectReferenceImpl.java Java example source code

/*
 * Copyright (c) 2002, 2009, 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.jdi;

import java.io.*;
import com.sun.jdi.*;

import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.debugger.OopHandle;
import sun.jvm.hotspot.oops.Oop;
import sun.jvm.hotspot.oops.Mark;
import sun.jvm.hotspot.oops.Instance;
import sun.jvm.hotspot.oops.Array;
import sun.jvm.hotspot.oops.OopUtilities;
import sun.jvm.hotspot.oops.Klass;
import sun.jvm.hotspot.oops.DefaultHeapVisitor;
import sun.jvm.hotspot.runtime.JavaThread;
import sun.jvm.hotspot.runtime.JavaVFrame;
import sun.jvm.hotspot.runtime.MonitorInfo;
import sun.jvm.hotspot.runtime.ObjectMonitor;
import sun.jvm.hotspot.runtime.Threads;
import sun.jvm.hotspot.utilities.Assert;

import java.util.*;

public class ObjectReferenceImpl extends ValueImpl implements ObjectReference {
    private Oop  saObject;
    private long myID;
    private boolean monitorInfoCached = false;
    private ThreadReferenceImpl owningThread = null;
    private List waitingThreads = null; // List<ThreadReferenceImpl>
    private int entryCount = 0;

    private static long nextID = 0L;
    private static synchronized long nextID() {
        return nextID++;
    }

    ObjectReferenceImpl(VirtualMachine aVm, sun.jvm.hotspot.oops.Oop oRef) {
        super(aVm);
        saObject = oRef;
        myID = nextID();
    }

    protected Oop ref() {
        return saObject;
    }

    public Type type() {
        return referenceType();
    }

    public ReferenceType referenceType() {
        Klass myKlass = ref().getKlass();
        return vm.referenceType(myKlass);
    }

    public Value getValue(Field sig) {
        List list = new ArrayList(1);
        list.add(sig);
        Map map = getValues(list);
        return(Value)map.get(sig);
    }

    public Map getValues(List theFields) {
        //validateMirrors(theFields);

        List staticFields = new ArrayList(0);
        int size = theFields.size();
        List instanceFields = new ArrayList(size);

        for (int i=0; i<size; i++) {
            sun.jvm.hotspot.jdi.FieldImpl field =
                (sun.jvm.hotspot.jdi.FieldImpl)theFields.get(i);

            // Make sure the field is valid
            ((ReferenceTypeImpl)referenceType()).validateFieldAccess(field);

            // FIX ME! We need to do some sanity checking
            // here; make sure the field belongs to this
            // object.
            if (field.isStatic()) {
                staticFields.add(field);
            } else {
                instanceFields.add(field);
            }
        }

        // Look up static field(s) first to mimic the JDI implementation
        Map map;
        if (staticFields.size() > 0) {
            map = referenceType().getValues(staticFields);
        } else {
            map = new HashMap(size);
        }

        // Then get instance field(s)
        size = instanceFields.size();
        for (int ii=0; ii<size; ii++){
            FieldImpl fieldImpl = (FieldImpl)instanceFields.get(ii);
            map.put(fieldImpl, fieldImpl.getValue(saObject));
        }

        return map;
    }

    public void setValue(Field field, Value value)
                   throws InvalidTypeException, ClassNotLoadedException {
        vm.throwNotReadOnlyException("ObjectReference.setValue(...)");
    }

    public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
                              List arguments, int options)
                              throws InvalidTypeException,
                                     IncompatibleThreadStateException,
                                     InvocationException,
                                     ClassNotLoadedException {
        vm.throwNotReadOnlyException("ObjectReference.invokeMethod(...)");
        return null;
    }

    public void disableCollection() {
        vm.throwNotReadOnlyException("ObjectReference.disableCollection()");
    }

    public void enableCollection() {
        vm.throwNotReadOnlyException("ObjectReference.enableCollection()");
    }

    public boolean isCollected() {
        vm.throwNotReadOnlyException("ObjectReference.isCollected()");
        return false;
    }

    public long uniqueID() {
        return myID;
    }

    public List waitingThreads() throws IncompatibleThreadStateException {
        if (vm.canGetMonitorInfo() == false) {
            throw new UnsupportedOperationException();
        }

        if (! monitorInfoCached) {
            computeMonitorInfo();
        }
        return waitingThreads;
    }


    public ThreadReference owningThread() throws IncompatibleThreadStateException {
        if (vm.canGetMonitorInfo() == false) {
            throw new UnsupportedOperationException();
        }

        if (! monitorInfoCached) {
            computeMonitorInfo();
        }
        return owningThread;
    }


    public int entryCount() throws IncompatibleThreadStateException {
        if (vm.canGetMonitorInfo() == false) {
            throw new UnsupportedOperationException();
        }

        if (! monitorInfoCached) {
            computeMonitorInfo();
        }
        return entryCount;
    }

    // new method since 1.6.
    // Real body will be supplied later.
    public List referringObjects(long maxReferrers) {
        if (!vm.canGetInstanceInfo()) {
            throw new UnsupportedOperationException(
                      "target does not support getting instances");
        }
        if (maxReferrers < 0) {
            throw new IllegalArgumentException("maxReferrers is less than zero: "
                                              + maxReferrers);
        }
        final ObjectReference obj = this;
        final List objects = new ArrayList(0);
        final long max = maxReferrers;
                vm.saObjectHeap().iterate(new DefaultHeapVisitor() {
                private long refCount = 0;
                public boolean doObj(Oop oop) {
                                        try {
                                                ObjectReference objref = vm.objectMirror(oop);
                                                List fields = objref.referenceType().allFields();
                                                for (int i=0; i < fields.size(); i++) {
                                                        Field fld = (Field)fields.get(i);
                                                        if (objref.getValue(fld).equals(obj) && !objects.contains(objref)) {
                                                                objects.add(objref);
                                                                refCount++;
                                                        }
                                                }
                                                if (max > 0 && refCount >= max) {
                                                        return true;
                                                }
                                        } catch  (RuntimeException x) {
                                          // Ignore RuntimeException thrown from vm.objectMirror(oop)
                                          // for bad oop. It is possible to see some bad oop
                                          // because heap might be iterating at no safepoint.
                                        }
                                        return false;

                }
            });
        return objects;
    }

    // refer to JvmtiEnvBase::count_locked_objects.
    // Count the number of objects for a lightweight monitor. The obj
    // parameter is object that owns the monitor so this routine will
    // count the number of times the same object was locked by frames
    // in JavaThread. i.e., we count total number of times the same
    // object is (lightweight) locked by given thread.
    private int countLockedObjects(JavaThread jt, Oop obj) {
        int res = 0;
        JavaVFrame frame = jt.getLastJavaVFrameDbg();
        while (frame != null) {
            List monitors = frame.getMonitors();
            OopHandle givenHandle = obj.getHandle();
            for (Iterator itr = monitors.iterator(); itr.hasNext();) {
                MonitorInfo mi = (MonitorInfo) itr.next();
                if (mi.eliminated() && frame.isCompiledFrame()) continue; // skip eliminated monitor
                if (givenHandle.equals(mi.owner())) {
                    res++;
                }
            }
            frame = (JavaVFrame) frame.javaSender();
        }
        return res;
    }

    // wrappers on same named method of Threads class
    // returns List<JavaThread>
    private List getPendingThreads(ObjectMonitor mon) {
        return vm.saVM().getThreads().getPendingThreads(mon);
    }

    // returns List<JavaThread>
    private List getWaitingThreads(ObjectMonitor mon) {
        return vm.saVM().getThreads().getWaitingThreads(mon);
    }

    private JavaThread owningThreadFromMonitor(Address addr) {
        return vm.saVM().getThreads().owningThreadFromMonitor(addr);
    }

    // refer to JvmtiEnv::GetObjectMonitorUsage
    private void computeMonitorInfo() {
        monitorInfoCached = true;
        Mark mark = saObject.getMark();
        ObjectMonitor mon = null;
        Address owner = null;
        // check for heavyweight monitor
        if (! mark.hasMonitor()) {
            // check for lightweight monitor
            if (mark.hasLocker()) {
                owner = mark.locker().getAddress(); // save the address of the Lock word
            }
            // implied else: no owner
        } else {
            // this object has a heavyweight monitor
            mon = mark.monitor();

            // The owner field of a heavyweight monitor may be NULL for no
            // owner, a JavaThread * or it may still be the address of the
            // Lock word in a JavaThread's stack. A monitor can be inflated
            // by a non-owning JavaThread, but only the owning JavaThread
            // can change the owner field from the Lock word to the
            // JavaThread * and it may not have done that yet.
            owner = mon.owner();
        }

        // find the owning thread
        if (owner != null) {
            owningThread = vm.threadMirror(owningThreadFromMonitor(owner));
        }

        // compute entryCount
        if (owningThread != null) {
            if (owningThread.getJavaThread().getAddress().equals(owner)) {
                // the owner field is the JavaThread *
                if (Assert.ASSERTS_ENABLED) {
                    Assert.that(false, "must have heavyweight monitor with JavaThread * owner");
                }
                entryCount = (int) mark.monitor().recursions() + 1;
            } else {
                // The owner field is the Lock word on the JavaThread's stack
                // so the recursions field is not valid. We have to count the
                // number of recursive monitor entries the hard way.
                entryCount = countLockedObjects(owningThread.getJavaThread(), saObject);
            }
        }

        // find the contenders & waiters
        waitingThreads = new ArrayList();
        if (mon != null) {
            // this object has a heavyweight monitor. threads could
            // be contenders or waiters
            // add all contenders
            List pendingThreads = getPendingThreads(mon);
            // convert the JavaThreads to ThreadReferenceImpls
            for (Iterator itrPend = pendingThreads.iterator(); itrPend.hasNext();) {
                waitingThreads.add(vm.threadMirror((JavaThread) itrPend.next()));
            }

            // add all waiters (threads in Object.wait())
            // note that we don't do this JVMTI way. To do it JVMTI way,
            // we would need to access ObjectWaiter list maintained in
            // ObjectMonitor::_queue. But we don't have this struct exposed
            // in vmStructs. We do waiters list in a way similar to getting
            // pending threads list
            List objWaitingThreads = getWaitingThreads(mon);
            // convert the JavaThreads to ThreadReferenceImpls
            for (Iterator itrWait = objWaitingThreads.iterator(); itrWait.hasNext();) {
                waitingThreads.add(vm.threadMirror((JavaThread) itrWait.next()));
            }
        }
    }

    public boolean equals(Object obj) {
        if ((obj != null) && (obj instanceof ObjectReferenceImpl)) {
            ObjectReferenceImpl other = (ObjectReferenceImpl)obj;
            return (ref().equals(other.ref())) &&
                   super.equals(obj);
        } else {
            return false;
        }
    }

    public int hashCode() {
        return saObject.hashCode();
    }

    public String toString() {
        return  "instance of " + referenceType().name() + "(id=" + uniqueID() + ")";
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java ObjectReferenceImpl.java 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.