Skip to content

Commit

Permalink
Reduce memory usage in MarkBasePointersPhase on JDK11.
Browse files Browse the repository at this point in the history
This implementation originates from the initial PR from
Xiaohong Gong <[email protected]> #1059
  • Loading branch information
Stefan Anzinger committed Feb 13, 2020
1 parent c0592ba commit 450c43b
Showing 1 changed file with 104 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -28,7 +28,6 @@
import org.graalvm.compiler.lir.LIR;
import org.graalvm.compiler.lir.LIRFrameState;
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.LIRValueUtil;
import org.graalvm.compiler.lir.Variable;
import org.graalvm.compiler.lir.framemap.FrameMap;
import org.graalvm.compiler.lir.gen.LIRGenerationResult;
Expand All @@ -40,6 +39,11 @@
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.meta.ValueKind;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
* Record all derived reference base pointers in a frame state.
*/
Expand All @@ -55,50 +59,103 @@ private static final class Marker extends LocationMarker<Marker.BasePointersSet>
private final class BasePointersSet extends ValueSet<Marker.BasePointersSet> {

private final IndexedValueMap variables;
private final Map<Integer, Set<Value>> baseDerivedRefs;

BasePointersSet() {
variables = new IndexedValueMap();
baseDerivedRefs = new HashMap<>();
}

private BasePointersSet(BasePointersSet s) {
variables = new IndexedValueMap(s.variables);
private BasePointersSet(BasePointersSet other) {
variables = new IndexedValueMap(other.variables);
// Deep copy.
baseDerivedRefs = new HashMap<>();
for (Map.Entry<Integer, Set<Value>> entry : other.baseDerivedRefs.entrySet()) {
Set<Value> s = new HashSet<>();
s.addAll(entry.getValue());
baseDerivedRefs.put(entry.getKey(), s);
}
}

@Override
public Marker.BasePointersSet copy() {
return new BasePointersSet(this);
}

// Verify that there is no base includes derivedRef already.
// The single derivedRef maps to multiple bases case can not happen.
private boolean verifyDerivedRefs(Value derivedRef, int base) {
for (Map.Entry<Integer, Set<Value>> entry : baseDerivedRefs.entrySet()) {
Set<Value> s = entry.getValue();
if (s.contains(derivedRef) && base != entry.getKey()) {
return false;
}
}
return true;
}

@Override
public void put(Value v) {
LIRKind lirKind = v.getValueKind(LIRKind.class);
if (lirKind.isDerivedReference()) {
// Only derived references are interesting usages.
Variable base = (Variable) lirKind.getDerivedReferenceBase();
assert !base.getValueKind(LIRKind.class).isValue();
variables.put(base.index, base);
Variable base = (Variable) v.getValueKind(LIRKind.class).getDerivedReferenceBase();
assert !base.getValueKind(LIRKind.class).isValue();
variables.put(base.index, base);

Set<Value> derivedRefs = baseDerivedRefs.get(base.index);
assert verifyDerivedRefs(v, base.index);
if (derivedRefs == null) {
HashSet<Value> s = new HashSet<>();
s.add(v);
baseDerivedRefs.put(base.index, s);
} else {
derivedRefs.add(v);
}
}

@Override
public void putAll(BasePointersSet v) {
variables.putAll(v.variables);

for (Map.Entry<Integer, Set<Value>> entry : v.baseDerivedRefs.entrySet()) {
Integer k = entry.getKey();
Set<Value> derivedRefsOther = entry.getValue();
Set<Value> derivedRefs = baseDerivedRefs.get(k);
if (derivedRefs == null) {
// Deep copy.
Set<Value> s = new HashSet<>();
s.addAll(derivedRefsOther);
baseDerivedRefs.put(k, s);
} else {
derivedRefs.addAll(derivedRefsOther);
}
}
}

@Override
public void remove(Value v) {
if (LIRValueUtil.isVariable(v)) {
// All (non-value) variables are potential base pointers.
Variable base = LIRValueUtil.asVariable(v);
Variable base = (Variable) v.getValueKind(LIRKind.class).getDerivedReferenceBase();
assert !base.getValueKind(LIRKind.class).isValue();
Set<Value> derivedRefs = baseDerivedRefs.get(base.index);
// Just mark the base pointer as null if no derived references exist.
if (derivedRefs == null) {
variables.put(base.index, null);
return;
}

// Remove the value from the derived reference set if the set exists.
if (derivedRefs.contains(v)) {
derivedRefs.remove(v);
if (derivedRefs.isEmpty()) {
variables.put(base.index, null);
baseDerivedRefs.remove(base.index);
}
}
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Marker.BasePointersSet) {
BasePointersSet other = (BasePointersSet) obj;
return variables.equals(other.variables);
return variables.equals(other.variables) && baseDerivedRefs.equals(other.baseDerivedRefs);
} else {
return false;
}
Expand All @@ -108,6 +165,36 @@ public boolean equals(Object obj) {
public int hashCode() {
throw new UnsupportedOperationException();
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[BasePointersSet] variables: ");
sb.append(variables.toString());
sb.append(" baseDerivedRefs map: {");

boolean mapHaveElement = false;
for (Map.Entry<Integer, Set<Value>> entry : baseDerivedRefs.entrySet()) {
sb.append(entry.getKey());
sb.append(": (");

boolean setHaveElement = false;
for (Value v : entry.getValue()) {
sb.append(v + ",");
setHaveElement = true;
}
if (setHaveElement) {
sb.deleteCharAt(sb.length() - 1);
}
sb.append("),");
mapHaveElement = true;
}
if (mapHaveElement) {
sb.deleteCharAt(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
}

private Marker(LIR lir, FrameMap frameMap) {
Expand All @@ -123,13 +210,10 @@ protected Marker.BasePointersSet newLiveValueSet() {
protected boolean shouldProcessValue(Value operand) {
ValueKind<?> kind = operand.getValueKind();
if (kind instanceof LIRKind) {
/*
* We are interested in all kinds that are not values (base pointers and derived
* references).
*/
return !((LIRKind) kind).isValue();
return ((LIRKind) kind).isDerivedReference();
} else {
return false;
}
return false;
}

@Override
Expand Down

0 comments on commit 450c43b

Please sign in to comment.