blob: 1b0a7ccdb189bcc0b9d706b592d07c1d0a4778cd [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.debugger.jpda.truffle;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.InvocationException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.StringReference;
import com.sun.jdi.VirtualMachine;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import org.netbeans.modules.debugger.jpda.jdi.InternalExceptionWrapper;
import org.netbeans.modules.debugger.jpda.jdi.ObjectCollectedExceptionWrapper;
import org.netbeans.modules.debugger.jpda.jdi.ObjectReferenceWrapper;
import org.netbeans.modules.debugger.jpda.jdi.UnsupportedOperationExceptionWrapper;
import org.netbeans.modules.debugger.jpda.jdi.VMDisconnectedExceptionWrapper;
import org.netbeans.modules.debugger.jpda.jdi.VirtualMachineWrapper;
/**
* Create values with disabled collection, which can be released later on.
* This is necessary e.g. for temporary variables so that they are not collected
* prematurely.
*/
public final class PersistentValues {
private final VirtualMachine vm;
private final List<ObjectReference> references = new ArrayList<>(5);
public PersistentValues(VirtualMachine vm) {
this.vm = vm;
}
public StringReference mirrorOf(String string) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, UnsupportedOperationExceptionWrapper {
StringReference stringMirror = null;
while (stringMirror == null) {
stringMirror = VirtualMachineWrapper.mirrorOf(vm, string);
try {
ObjectReferenceWrapper.disableCollection(stringMirror);
} catch (ObjectCollectedExceptionWrapper ce) {
stringMirror = null;
}
}
references.add(stringMirror);
return stringMirror;
}
/**
* @return the reference or <code>null</code> in case of JDI exceptions.
*/
public StringReference mirrorOf0(String string) {
try {
return mirrorOf(string);
} catch (InternalExceptionWrapper | UnsupportedOperationExceptionWrapper | VMDisconnectedExceptionWrapper e) {
return null;
}
}
public <T extends ObjectReference> T valueOf(ValueSupplier<T> valueSupplier) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, UnsupportedOperationExceptionWrapper {
T value = null;
while (value == null) {
value = valueSupplier.get();
try {
ObjectReferenceWrapper.disableCollection(value);
} catch (ObjectCollectedExceptionWrapper ce) {
value = null;
}
}
references.add(value);
return value;
}
public <T extends ObjectReference> T invokeOf(InvokeSupplier<T> valueSupplier) throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, UnsupportedOperationExceptionWrapper, ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException, InvocationException, ObjectCollectedExceptionWrapper {
T value = null;
while (value == null) {
value = valueSupplier.get();
try {
ObjectReferenceWrapper.disableCollection(value);
} catch (ObjectCollectedExceptionWrapper ce) {
value = null;
}
}
references.add(value);
return value;
}
public void collect() {
for (ObjectReference reference : references) {
try {
ObjectReferenceWrapper.enableCollection(reference);
} catch (InternalExceptionWrapper | ObjectCollectedExceptionWrapper | UnsupportedOperationExceptionWrapper ex) {
// continue
} catch (VMDisconnectedExceptionWrapper ex) {
break;
}
}
references.clear();
}
@FunctionalInterface
public interface ValueSupplier<T> {
public T get() throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, UnsupportedOperationExceptionWrapper;
}
@FunctionalInterface
public interface InvokeSupplier<T> {
public T get() throws InternalExceptionWrapper, VMDisconnectedExceptionWrapper, UnsupportedOperationExceptionWrapper, ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException, InvocationException, ObjectCollectedExceptionWrapper;
}
}