blob: 1358675856e4508e3478f940657627ff207a6ab0 [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed 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 com.android.tools.perflib.heap.analysis;
import com.android.tools.perflib.heap.ClassInstance;
import com.android.tools.perflib.heap.ClassObj;
import com.android.tools.perflib.heap.Field;
import com.android.tools.perflib.heap.RootObj;
import com.android.tools.perflib.heap.RootType;
import com.android.tools.perflib.heap.Snapshot;
import com.android.tools.perflib.heap.Type;
import com.android.tools.perflib.heap.io.InMemoryBuffer;
import java.nio.ByteBuffer;
/**
* Utility for creating Snapshot objects to be used in tests.
*
* As the main concern here is graph connectivity, we only initialize the app heap, creating
* ClassInstance objects with id in [1..numNodes], each instance pointing to a unique ClassObj.
* The class ids range in [101..100+numNodes] and their size is set to match the id of their object
* instance. The default heap holds the roots.
*/
public class SnapshotBuilder {
private final Snapshot mSnapshot;
private final ClassInstance[] mNodes;
private final int[] mOffsets;
private final ByteBuffer mDirectBuffer;
public SnapshotBuilder(int numNodes) {
Type.setIdSize(2); // A good opportunity to test the handling of short IDs.
InMemoryBuffer buffer = new InMemoryBuffer(2 * numNodes * numNodes);
mDirectBuffer = buffer.getDirectBuffer();
mOffsets = new int[numNodes + 1];
mSnapshot = new Snapshot(buffer);
mSnapshot.setHeapTo(13, "testHeap");
mNodes = new ClassInstance[numNodes + 1];
for (int i = 1; i <= numNodes; i++) {
ClassObj clazz = new ClassObj(100 + i, null, "Class" + i, 0);
clazz.setFields(new Field[0]);
mSnapshot.addClass(100 + i, clazz);
mOffsets[i] = 2 * (i - 1) * numNodes;
mNodes[i] = new ClassInstance(i, null, mOffsets[i]);
mNodes[i].setClassId(100 + i);
mNodes[i].setSize(i);
mSnapshot.addInstance(i, mNodes[i]);
}
}
public SnapshotBuilder addReferences(int nodeFrom, int... nodesTo) {
Field[] fields = new Field[nodesTo.length];
for (int i = 0; i < nodesTo.length; i++) {
mDirectBuffer.putShort(mOffsets[nodeFrom] + i * 2, (short) nodesTo[i]);
fields[i] = new Field(Type.OBJECT, "f" + nodesTo[i]);
}
mNodes[nodeFrom].getClassObj().setFields(fields);
return this;
}
public SnapshotBuilder addRoot(int node) {
RootObj root = new RootObj(RootType.JAVA_LOCAL, node);
mSnapshot.setToDefaultHeap();
mSnapshot.addRoot(root);
return this;
}
public Snapshot getSnapshot() {
return mSnapshot;
}
}