Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/HeapwalkingDebugger.java
41161 views
/*1* Copyright (c) 2006, 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*/22package nsk.share.jdi;2324import java.util.*;25import com.sun.jdi.*;26import nsk.share.TestBug;2728/*29* Debugger class used in tests for heapwalking(tests for VirtualMachine.instanceCounts, ReferenceType.instances, ObjectReference.referrers)30* Contains several common checking and auxiliary methods.31*/32public class HeapwalkingDebugger extends TestDebuggerType2 {33// instances of some classes couldn't be strictly controlled during test execution, use non-strict checks for this classes34protected boolean strictCheck(String className) {35if (className.equals("java.lang.String"))36return false;3738if (className.equals("char[]"))39return false;4041if (className.equals("byte[]"))42return false;4344if (className.equals("boolean[]"))45return false;4647if (className.equals("float[]"))48return false;4950if (className.equals("long[]"))51return false;5253if (className.equals("int[]"))54return false;5556if (className.equals("double[]"))57return false;5859if (className.equals("java.lang.Thread")) {60return !isJFRActive();61}6263return true;64}6566protected boolean isJFRActive() {67ReferenceType referenceType = debuggee.classByName("nsk.share.jdi.HeapwalkingDebuggee");68if (referenceType == null)69throw new RuntimeException("Debugeee is not initialized yet");7071Field isJFRActiveFld = referenceType.fieldByName("isJFRActive");72boolean isJFRActive = ((BooleanValue)referenceType.getValue(isJFRActiveFld)).value();73return isJFRActive;74}7576// wrapper for VirtualMachine.instanceCounts77public long getInstanceCount(String className) {78List<ReferenceType> list = vm.classesByName(className);7980if (list.size() == 0)81return 0;8283if (list.size() > 1) {84setSuccess(false);85log.complain("Unexpected collection size returned by VirtualMachine.classesByName(" + className + "): " + list.size()86+ ", only 1 entry was expected.");87}8889long result[] = (vm.instanceCounts(list));9091return result[0];92}9394// tests that vm.instanceCounts(vm.allClasses()) doesn't throws any exceptions95protected void testInstanceCounts() {96try {97vm.instanceCounts(vm.allClasses());98} catch (Throwable t) {99setSuccess(false);100log.complain("Unexpected exception: " + t);101t.printStackTrace(log.getOutStream());102}103104}105106// check size of list returned by ReferenceType.instances107protected void checkDebugeeAnswer_instances(String className, int expectedCount) {108ReferenceType referenceType = debuggee.classByName(className);109110int instanceCounts = referenceType.instances(0).size();111112if (strictCheck(className)) {113if (referenceType.instances(0).size() != expectedCount) {114setSuccess(false);115log.complain("Unexpected size of referenceType.instances(" + className + "): " + instanceCounts + ", expected: " + expectedCount);116}117} else {118if (referenceType.instances(0).size() < expectedCount) {119setSuccess(false);120log.complain("Unexpected size of referenceType.instances(" + className + "): " + instanceCounts + ", expected: >= " + expectedCount);121}122}123}124125// check value returned by VirtualMachine.instanceCounts,126// note that method call method isDebuggeeReady() which check that debuggee completed pervious command and is ready for new one127public void checkDebugeeAnswer_instanceCounts(String className, int expectedValue) {128if (!isDebuggeeReady())129return;130131try {132long instanceCounts = getInstanceCount(className);133134if (strictCheck(className)) {135if (instanceCounts != expectedValue) {136setSuccess(false);137log.complain("Wrong value was returned by VirtualMachine.instanceCounts(" + className + "): " + instanceCounts + ", expected: "138+ expectedValue);139}140} else {141if (instanceCounts < expectedValue) {142setSuccess(false);143log.complain("Wrong value was returned by VirtualMachine.instanceCounts(" + className + "): " + instanceCounts144+ ", expected: >= " + expectedValue);145}146}147} catch (Throwable e) {148setSuccess(false);149150log.complain("Unexpected exception when getting instance count info:");151e.printStackTrace(log.getOutStream());152}153}154155// Verifies number of instances of a class.156// Two types of checks are done:157// 1. Current instances >= old instances + created instances.158// 2. New instances >= created instances.159//160// The check in case 1 can only be done for classes where the test controls161// all created and deleted instances.162// Other classes, like java.lang.String, can not make this check since163// an instance in "old instances" may have been removed by a GC.164// In that case the tetst would fail because it finds too few current instances.165public void checkDebugeeAnswer_instanceCounts(String className, int countCreated, List<ObjectReference> oldReferences) {166if (strictCheck(className)) {167int countAll = countCreated + oldReferences.size();168checkDebugeeAnswer_instanceCounts(className, countAll);169checkDebugeeAnswer_instances(className, countAll);170} else {171// isDebuggeeReady() check is hidden in checkDebugeeAnswer_instanceCounts() above.172// Must call it separately if we don't call checkDebugeeAnswer_instanceCounts().173if (!isDebuggeeReady()) {174return;175}176}177178// Verify number of new instances created.179int countFoundCreated = countNewInstances(className, oldReferences);180if (countFoundCreated < countCreated) {181setSuccess(false);182log.complain("Too few new instances(" + className + "). Expected >= " + countCreated + ", found " + countFoundCreated);183}184}185186private int countNewInstances(String className, List<ObjectReference> oldReferences) {187// New references = current references - old references.188List<ObjectReference> newReferences = new ArrayList<ObjectReference>(getObjectReferences(className, vm));189newReferences.removeAll(oldReferences);190return newReferences.size();191}192193// check value returned by InterfaceType.instances194protected void checkDebugeeAnswer_InterfaceType_instances(InterfaceType interfaceType, int expectedInstances) {195int instanceCounts = interfaceType.instances(0).size();196197if (instanceCounts != expectedInstances) {198setSuccess(false);199log.complain("List with wrong size was returned by InterfaceType.instances(" + interfaceType.name() + "): " + instanceCounts200+ ", expected: " + expectedInstances);201}202}203204static public List<ObjectReference> filterObjectReferrence(List<ObjectReference> objectsToFilter, List<ObjectReference> sourceList) {205List<ObjectReference> result = new ArrayList<ObjectReference>();206207for (ObjectReference object : sourceList) {208if (!objectsToFilter.contains(object))209result.add(object);210}211212return result;213}214215static public List<ObjectReference> getObjectReferences(String className, VirtualMachine vm) {216List<ReferenceType> referenceTypes = vm.classesByName(className);217218List<ObjectReference> objectReferences;219220if (referenceTypes.size() == 0)221objectReferences = new ArrayList<ObjectReference>();222else if (referenceTypes.size() == 1)223objectReferences = referenceTypes.get(0).instances(0);224else {225throw new TestBug("Unexpected collection size returned by VirtualMachine.classesByName: " + referenceTypes.size()226+ ", only 1 entry was expected.");227}228229return objectReferences;230}231232}233234235