blob: d632a0380a4c72f5e04ae747f556c2808c4f29cc [file] [log] [blame]
// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.code.frame.FrameType;
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectSortedMap;
public class CfFrameUtils {
public static void storeLocal(
int localIndex, FrameType frameType, Int2ObjectAVLTreeMap<FrameType> locals) {
assert !frameType.isTwoWord();
// Write low register.
FrameType previousType = locals.put(localIndex, frameType);
// Set low register -1 to top if it is the start of a wide primitive.
if (previousType != null && previousType.isWidePrimitiveHigh()) {
FrameType previousLowType = locals.put(localIndex - 1, FrameType.oneWord());
assert previousLowType == previousType.asWidePrimitive().getLowType();
}
// Write high register.
if (frameType.isWidePrimitive()) {
assert frameType.isWidePrimitiveLow();
previousType = locals.put(localIndex + 1, frameType.asWidePrimitive().getHighType());
}
// Set high register + 1 to top if it is the end of a wide primitive.
if (previousType != null && previousType.isWidePrimitiveLow()) {
FrameType previousHighType =
locals.put(localIndex + frameType.getWidth(), FrameType.oneWord());
assert previousHighType == previousType.asWidePrimitive().getHighType();
}
}
public static boolean verifyLocals(Int2ObjectSortedMap<FrameType> locals) {
for (Int2ObjectMap.Entry<FrameType> entry : locals.int2ObjectEntrySet()) {
int localIndex = entry.getIntKey();
FrameType frameType = entry.getValue();
if (frameType.isWidePrimitiveLow()) {
assert locals.get(localIndex + 1) == frameType.asWidePrimitive().getHighType();
} else if (frameType.isWidePrimitiveHigh()) {
assert locals.get(localIndex - 1) == frameType.asWidePrimitive().getLowType();
} else {
assert !frameType.isTwoWord();
}
}
return true;
}
}