mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
explicitly remove smartpointers to decrease GC strain
This commit is contained in:
@@ -60,4 +60,5 @@ public abstract class SmartPointerManager {
|
||||
* @return true if both pointers point to the same PSI element.
|
||||
*/
|
||||
public abstract boolean pointToTheSameElement(@NotNull SmartPsiElementPointer pointer1, @NotNull SmartPsiElementPointer pointer2);
|
||||
public abstract boolean removePointer(@NotNull SmartPsiElementPointer pointer);
|
||||
}
|
||||
|
||||
@@ -205,8 +205,9 @@ public abstract class ElementBase extends UserDataHolderBase implements Iconable
|
||||
@Nullable
|
||||
public PsiElement getElement() {
|
||||
if (myPointer.getProject().isDisposed()) return null;
|
||||
|
||||
return myPointer.getElement();
|
||||
PsiElement element = myPointer.getElement();
|
||||
SmartPointerManager.getInstance(myPointer.getProject()).removePointer(myPointer);
|
||||
return element;
|
||||
}
|
||||
|
||||
@Iconable.IconFlags
|
||||
|
||||
@@ -84,4 +84,9 @@ public class ClsElementInfo implements SmartPointerElementInfo {
|
||||
public Project getProject() {
|
||||
return myStubIndexReference.getProject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,4 +94,9 @@ class FileElementInfo implements SmartPointerElementInfo {
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,4 +80,9 @@ class HardElementInfo implements SmartPointerElementInfo {
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -116,4 +116,10 @@ class InjectedSelfElementInfo extends SelfElementInfo {
|
||||
SmartPointerElementInfo oElementInfo = ((SmartPsiElementPointerImpl)((InjectedSelfElementInfo)other).myInjectedFileRangeInHostFile).getElementInfo();
|
||||
return myElementInfo.pointsToTheSameElementAs(oElementInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
super.cleanup();
|
||||
SmartPointerManager.getInstance(getProject()).removePointer(myInjectedFileRangeInHostFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +205,15 @@ public class SelfElementInfo implements SmartPointerElementInfo {
|
||||
return ref == null ? null : ref.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
RangeMarker marker = getMarker();
|
||||
if (marker != null) marker.dispose();
|
||||
unfastenBelt(0);
|
||||
setMarker(null);
|
||||
mySyncMarkerIsValid = false;
|
||||
}
|
||||
|
||||
private void setMarker(RangeMarker marker) {
|
||||
myMarkerRef = marker == null ? null : new SoftReference<RangeMarker>(marker);
|
||||
}
|
||||
|
||||
+2
@@ -44,4 +44,6 @@ interface SmartPointerElementInfo {
|
||||
@Nullable
|
||||
Segment getRange();
|
||||
@NotNull Project getProject();
|
||||
|
||||
void cleanup();
|
||||
}
|
||||
|
||||
+30
-11
@@ -106,7 +106,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static final Key<Reference<SmartPsiElementPointer>> CACHED_SMART_POINTER_KEY = Key.create("CACHED_SMART_POINTER_KEY");
|
||||
private static final Key<Reference<SmartPointerEx>> CACHED_SMART_POINTER_KEY = Key.create("CACHED_SMART_POINTER_KEY");
|
||||
@Override
|
||||
@NotNull
|
||||
public <E extends PsiElement> SmartPsiElementPointer<E> createSmartPsiElementPointer(@NotNull E element) {
|
||||
@@ -120,22 +120,26 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
if (containingFile != null && !containingFile.isValid() || containingFile == null && !element.isValid()) {
|
||||
LOG.error("Invalid element:" + element);
|
||||
}
|
||||
SmartPsiElementPointer<E> cachedPointer = getCachedPointer(element);
|
||||
SmartPointerEx<E> cachedPointer = getCachedPointer(element);
|
||||
if (cachedPointer != null) {
|
||||
containingFile = containingFile == null ? element.getContainingFile() : containingFile;
|
||||
if (containingFile != null && areBeltsFastened(containingFile)) {
|
||||
cachedPointer.fastenBelt(0, null);
|
||||
}
|
||||
return cachedPointer;
|
||||
}
|
||||
|
||||
SmartPointerEx<E> pointer = new SmartPsiElementPointerImpl<E>(myProject, element, containingFile);
|
||||
initPointer(pointer, containingFile);
|
||||
element.putUserData(CACHED_SMART_POINTER_KEY, new SoftReference<SmartPsiElementPointer>(pointer));
|
||||
element.putUserData(CACHED_SMART_POINTER_KEY, new SoftReference<SmartPointerEx>(pointer));
|
||||
return pointer;
|
||||
}
|
||||
|
||||
private static <E extends PsiElement> SmartPsiElementPointer<E> getCachedPointer(@NotNull E element) {
|
||||
Reference<SmartPsiElementPointer> data = element.getUserData(CACHED_SMART_POINTER_KEY);
|
||||
SmartPsiElementPointer cachedPointer = data == null ? null : data.get();
|
||||
if (cachedPointer instanceof SmartPointerEx) {
|
||||
PsiElement cachedElement = ((SmartPointerEx)cachedPointer).getCachedElement();
|
||||
private static <E extends PsiElement> SmartPointerEx<E> getCachedPointer(@NotNull E element) {
|
||||
Reference<SmartPointerEx> data = element.getUserData(CACHED_SMART_POINTER_KEY);
|
||||
SmartPointerEx cachedPointer = data == null ? null : data.get();
|
||||
if (cachedPointer != null) {
|
||||
PsiElement cachedElement = cachedPointer.getCachedElement();
|
||||
if (cachedElement != null && cachedElement != element) {
|
||||
return null;
|
||||
}
|
||||
@@ -160,7 +164,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
synchronized (lock) {
|
||||
List<SmartPointerEx> pointers = getPointers(containingFile);
|
||||
if (pointers == null) {
|
||||
pointers = new UnsafeWeakList<SmartPointerEx>(); // we synchronise access anyway by containingFile
|
||||
pointers = new UnsafeWeakList<SmartPointerEx>(); // we synchronise access anyway
|
||||
containingFile.putUserData(SMART_POINTERS_IN_PSI_FILE_KEY, pointers);
|
||||
}
|
||||
pointers.add(pointer);
|
||||
@@ -171,14 +175,29 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removePointer(@NotNull SmartPsiElementPointer pointer) {
|
||||
synchronized (lock) {
|
||||
PsiFile containingFile = pointer.getContainingFile();
|
||||
if (containingFile == null) return false;
|
||||
List<SmartPointerEx> pointers = getPointers(containingFile);
|
||||
if (pointers == null) return false;
|
||||
SmartPointerElementInfo info = ((SmartPsiElementPointerImpl)pointer).getElementInfo();
|
||||
info.cleanup();
|
||||
return pointers.remove(pointer);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<SmartPointerEx> getPointers(@NotNull PsiFile containingFile) {
|
||||
return containingFile.getUserData(SMART_POINTERS_IN_PSI_FILE_KEY);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public int getPointersNumber(@NotNull PsiFile containingFile) {
|
||||
List<SmartPointerEx> pointers = getPointers(containingFile);
|
||||
return pointers == null ? 0 : pointers.size();
|
||||
synchronized (lock) {
|
||||
List<SmartPointerEx> pointers = getPointers(containingFile);
|
||||
return pointers == null ? 0 : pointers.size();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean areBeltsFastened(@NotNull PsiFile file) {
|
||||
|
||||
+7
-7
@@ -98,9 +98,8 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
|
||||
final PsiElement formatted = SourceTreeToPsiMap.treeElementToPsi(new CodeFormatterFacade(getSettings()).processElement(treeElement));
|
||||
if (!canChangeWhiteSpacesOnly) {
|
||||
return postProcessElement(formatted);
|
||||
} else {
|
||||
return formatted;
|
||||
}
|
||||
return formatted;
|
||||
}
|
||||
|
||||
private PsiElement postProcessElement(@NotNull final PsiElement formatted) {
|
||||
@@ -234,6 +233,8 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
|
||||
postProcessText(file, new TextRange(info.fromStart ? 0 : startElement.getTextRange().getStartOffset(),
|
||||
info.toEnd ? file.getTextLength() : endElement.getTextRange().getEndOffset()));
|
||||
}
|
||||
if (info.startPointer != null) smartPointerManager.removePointer(info.startPointer);
|
||||
if (info.endPointer != null) smartPointerManager.removePointer(info.endPointer);
|
||||
}
|
||||
|
||||
if (editor == null) {
|
||||
@@ -794,11 +795,10 @@ public class CodeStyleManagerImpl extends CodeStyleManager {
|
||||
}
|
||||
|
||||
private static class RangeFormatInfo{
|
||||
|
||||
public final SmartPsiElementPointer startPointer;
|
||||
public final SmartPsiElementPointer endPointer;
|
||||
public final boolean fromStart;
|
||||
public final boolean toEnd;
|
||||
private final SmartPsiElementPointer startPointer;
|
||||
private final SmartPsiElementPointer endPointer;
|
||||
private final boolean fromStart;
|
||||
private final boolean toEnd;
|
||||
|
||||
RangeFormatInfo(@Nullable SmartPsiElementPointer startPointer,
|
||||
@Nullable SmartPsiElementPointer endPointer,
|
||||
|
||||
@@ -41,6 +41,8 @@ import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.SmartPointerManager;
|
||||
import com.intellij.psi.SmartPsiElementPointer;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.components.JBTabbedPane;
|
||||
import com.intellij.ui.content.Content;
|
||||
@@ -1030,6 +1032,19 @@ public class UsageViewImpl implements UsageView, UsageModelTracker.UsageModelTra
|
||||
myModelTracker.removeListener(this);
|
||||
myUpdateAlarm.cancelAllRequests();
|
||||
}
|
||||
disposeSmartPointers();
|
||||
}
|
||||
|
||||
private void disposeSmartPointers() {
|
||||
SmartPointerManager pointerManager = SmartPointerManager.getInstance(getProject());
|
||||
for (Usage usage : myUsageNodes.keySet()) {
|
||||
if (usage instanceof UsageInfo2UsageAdapter) {
|
||||
SmartPsiElementPointer<?> pointer = ((UsageInfo2UsageAdapter)usage).getUsageInfo().getSmartPointer();
|
||||
if (pointer != null) {
|
||||
pointerManager.removePointer(pointer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user