Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JNIHandleBlock.java
41161 views
/*1* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324package sun.jvm.hotspot.runtime;2526import java.util.*;27import sun.jvm.hotspot.debugger.*;28import sun.jvm.hotspot.runtime.*;29import sun.jvm.hotspot.types.*;30import sun.jvm.hotspot.utilities.*;31import sun.jvm.hotspot.utilities.Observable;32import sun.jvm.hotspot.utilities.Observer;3334/** */35public class JNIHandleBlock extends VMObject {36private static Field handlesField;37private static CIntegerField topField;38private static AddressField nextField;3940private static int blockSizeInOops;4142static {43VM.registerVMInitializedObserver(new Observer() {44public void update(Observable o, Object data) {45initialize(VM.getVM().getTypeDataBase());46}47});48}4950private static synchronized void initialize(TypeDataBase db) {51Type type = db.lookupType("JNIHandleBlock");5253handlesField = type.getField("_handles");54topField = type.getCIntegerField("_top");55nextField = type.getAddressField("_next");5657blockSizeInOops = db.lookupIntConstant("JNIHandleBlock::block_size_in_oops").intValue();58}5960public JNIHandleBlock(Address addr) {61super(addr);62}6364public JNIHandleBlock next() {65Address handleAddr = nextField.getValue(addr);66if (handleAddr == null) {67return null;68}6970/* the next handle block is valid only if the current block is full */71if (top() < blockSizeInOops) {72return null;73}74return new JNIHandleBlock(handleAddr);75}7677public int top() {78return (int) topField.getValue(addr);79}8081public void oopsDo(AddressVisitor visitor) {82// Visit handles in this block83for (int i = 0; i < top(); i++) {84Address cur = getOopHandleAddress(i);85if (cur != null) {86visitor.visitAddress(cur);87}88}8990// Visit handles in subsequent blocks if necessary91JNIHandleBlock n = next();92if (n != null) {93n.oopsDo(visitor);94}95}9697public OopHandle getOopHandle(int x) {98Address oopAddr = getOopHandleAddress(x);99if (oopAddr != null) {100return oopAddr.getOopHandleAt(0);101}102return null;103}104105/** Debugging routine only. Returns non-null JNIHandleBlock106containing the JNI handle or null if this handle block and its107successors did not contain it. */108public JNIHandleBlock blockContainingHandle(Address jniHandle) {109JNIHandleBlock cur = this;110while (cur != null) {111if (indexOfHandle(jniHandle) >= 0) {112return cur;113}114cur = cur.next();115}116return null;117}118119/** Debugging routine: returns the index (0..top() - 1) of the120handle in this block, or -1 if the handle was not contained in121this block. Does not search successor blocks. */122public int indexOfHandle(Address jniHandle) {123for (int i = 0; i < top(); i++) {124Address addr = getOopHandleAddress(i);125if (addr != null) {126if (addr.equals(jniHandle)) {127return i;128}129}130}131return -1;132}133134public String toString() {135Address handleBase = addr.addOffsetTo(handlesField.getOffset());136Address handleEnd = addr.addOffsetTo(handlesField.getOffset() + top() * VM.getVM().getOopSize());137return "JNIHandleBlock [" + handleBase + ", " + handleEnd + ")";138}139140/** Only returns addresses of valid OopHandles */141private Address getOopHandleAddress(int x) {142if (Assert.ASSERTS_ENABLED) {143Assert.that(x < top(), "out of bounds");144}145146Address oopAddr = addr.addOffsetTo(handlesField.getOffset() + x * VM.getVM().getOopSize());147OopHandle handle = oopAddr.getOopHandleAt(0);148if (VM.getVM().getUniverse().isInReserved(handle)) {149/* the oop handle is valid only if it is not freed (i.e. reserved in heap) */150return oopAddr;151} else {152return null;153}154}155}156157158