Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/code/StubQueue.java
41171 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.code;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/** <P> A port of the VM's StubQueue. Note that the VM implicitly35knows the type of the objects contained in each StubQueue because36it passes in an instance of a StubInterface to the StubQueue's37constructor; the goal in the VM was to save space in the generated38code. In the SA APIs the pattern has been to use the39VirtualConstructor mechanism to instantiate wrapper objects of the40appropriate type for objects down in the VM; see, for example, the41CodeCache, which identifies NMethods, RuntimeStubs, etc. </P>4243<P> In this port we eliminate the StubInterface in favor of44passing in the class corresponding to the type of Stub which this45StubQueue contains. </P> */4647public class StubQueue extends VMObject {48// FIXME: add the rest of the fields49private static AddressField stubBufferField;50private static CIntegerField bufferLimitField;51private static CIntegerField queueBeginField;52private static CIntegerField queueEndField;53private static CIntegerField numberOfStubsField;5455// The type of the contained stubs (i.e., InterpreterCodelet,56// ICStub). Must be a subclass of type Stub.57private Class<?> stubType;5859static {60VM.registerVMInitializedObserver(new Observer() {61public void update(Observable o, Object data) {62initialize(VM.getVM().getTypeDataBase());63}64});65}6667private static synchronized void initialize(TypeDataBase db) {68Type type = db.lookupType("StubQueue");6970stubBufferField = type.getAddressField("_stub_buffer");71bufferLimitField = type.getCIntegerField("_buffer_limit");72queueBeginField = type.getCIntegerField("_queue_begin");73queueEndField = type.getCIntegerField("_queue_end");74numberOfStubsField = type.getCIntegerField("_number_of_stubs");75}7677public StubQueue(Address addr, Class stubType) {78super(addr);79this.stubType = stubType;80}8182public boolean contains(Address pc) {83if (pc == null) return false;84long offset = pc.minus(getStubBuffer());85return ((0 <= offset) && (offset < getBufferLimit()));86}8788public Stub getStubContaining(Address pc) {89if (contains(pc)) {90int i = 0;91for (Stub s = getFirst(); s != null; s = getNext(s)) {92if (stubContains(s, pc)) {93return s;94}95}96}97return null;98}99100public boolean stubContains(Stub s, Address pc) {101return (s.codeBegin().lessThanOrEqual(pc) && s.codeEnd().greaterThan(pc));102}103104public int getNumberOfStubs() {105return (int) numberOfStubsField.getValue(addr);106}107108public Stub getFirst() {109return ((getNumberOfStubs() > 0) ? getStubAt(getQueueBegin()) : null);110}111112public Stub getNext(Stub s) {113long i = getIndexOf(s) + getStubSize(s);114if (i == getBufferLimit()) {115i = 0;116}117return ((i == getQueueEnd()) ? null : getStubAt(i));118}119120public Stub getPrev(Stub s) {121if (getIndexOf(s) == getQueueBegin()) {122return null;123}124125Stub temp = getFirst();126Stub prev = null;127while (temp != null && getIndexOf(temp) != getIndexOf(s)) {128prev = temp;129temp = getNext(temp);130}131132return prev;133}134135//--------------------------------------------------------------------------------136// Internals only below this point137//138139private long getQueueBegin() {140return queueBeginField.getValue(addr);141}142143private long getQueueEnd() {144return queueEndField.getValue(addr);145}146147private long getBufferLimit() {148return bufferLimitField.getValue(addr);149}150151private Address getStubBuffer() {152return stubBufferField.getValue(addr);153}154155private Stub getStubAt(long offset) {156checkIndex(offset);157return (Stub) VMObjectFactory.newObject(stubType, getStubBuffer().addOffsetTo(offset));158}159160private long getIndexOf(Stub s) {161long i = s.getAddress().minus(getStubBuffer());162checkIndex(i);163return i;164}165166private long getStubSize(Stub s) {167return s.getSize();168}169170private void checkIndex(long i) {171if (Assert.ASSERTS_ENABLED) {172Assert.that(0 <= i && i < getBufferLimit() && (i % VM.getVM().getAddressSize() == 0), "illegal index");173}174}175}176177178