[vm] Adding static_field_offset to Field objects.

This adds the offset of static fields within their field table.

TEST=vm/dart/analyze_snapshot_binary_test

Change-Id: I90b13760fa3203ca2e3c5611e3fd890a74c97728
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429880
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Roy
2025-05-23 12:45:41 -07:00
committed by Commit Queue
parent 0f34fdde1d
commit c9ba43db45
3 changed files with 31 additions and 17 deletions
@@ -16,6 +16,7 @@ import 'use_flag_test_helper.dart';
const int headerSize = 8;
final int compressedWordSize =
sizeOf<Pointer>() == 8 && !Platform.executable.contains('64C') ? 8 : 4;
const int wordSize = 8; // analyze_snapshot is not supported on arm32
// Used to ensure we don't have multiple equivalent calls to test.
final _seenDescriptions = <String>{};
@@ -222,7 +223,8 @@ Future<void> testAOT(
// We have:
// class Base {
// static int baseS = int.parse('1');
// static int baseS0 = int.parse('1');
// static int baseS1 = int.parse('2');
// int base0;
// double base1;
// Object? base2;
@@ -231,10 +233,17 @@ Future<void> testAOT(
// }
//
// This static field is never tree shaken.
expectField(baseFields[0], name: 'baseS', flags: ['static']);
expectField(baseFields[0], name: 'baseS0', flags: ['static']);
expectField(baseFields[1], name: 'baseS1', flags: ['static']);
// Neighboring static fields should always be one word away
final int staticFieldOffset0 = baseFields[0]["static_field_offset"];
final int staticFieldOffset1 = baseFields[1]["static_field_offset"];
Expect.equals(staticFieldOffset1 - staticFieldOffset0, wordSize);
if (isProduct) {
// Most [Field] objests are tree shaken.
Expect.equals(1, baseFields.length);
Expect.equals(2, baseFields.length);
int slotOffset = 0;
slotOffset += expectUnknown8Bytes(
@@ -264,28 +273,28 @@ Future<void> testAOT(
);
} else {
// We don't tree shake [Field] objects in non-product builds.
Expect.equals(6, baseFields.length);
Expect.equals(7, baseFields.length);
expectField(
baseFields[1],
baseFields[2],
name: 'base0',
isReference: false,
unboxedType: 'int',
);
expectField(
baseFields[2],
baseFields[3],
name: 'base1',
isReference: false,
unboxedType: 'double',
);
expectField(baseFields[3], name: 'base2');
expectField(baseFields[4], name: 'base2');
expectField(
baseFields[4],
baseFields[5],
name: 'base3',
isReference: false,
unboxedType: 'Float32x4',
);
expectField(
baseFields[5],
baseFields[6],
name: 'base4',
isReference: false,
unboxedType: 'Float64x2',
@@ -296,34 +305,34 @@ Future<void> testAOT(
offsetReferences: 0,
offsetBytes: 0,
isReference: false,
fieldId: baseFieldIds[1],
fieldId: baseFieldIds[2],
);
slotOffset += expectInstanceSlot(
baseSlots[slotOffset],
offsetReferences: 0,
offsetBytes: 8,
isReference: false,
fieldId: baseFieldIds[2],
fieldId: baseFieldIds[3],
);
slotOffset += expectInstanceSlot(
baseSlots[slotOffset],
offsetReferences: 0,
offsetBytes: 16,
fieldId: baseFieldIds[3],
fieldId: baseFieldIds[4],
);
slotOffset += expectInstanceSlot(
baseSlots[slotOffset],
offsetReferences: 1,
offsetBytes: 16,
isReference: false,
fieldId: baseFieldIds[4],
fieldId: baseFieldIds[5],
);
slotOffset += expectInstanceSlot(
baseSlots[slotOffset],
offsetReferences: 1,
offsetBytes: 32,
isReference: false,
fieldId: baseFieldIds[5],
fieldId: baseFieldIds[6],
);
}
// We have:
@@ -40,7 +40,8 @@ main() {
}
class FieldTestBase {
static int baseS = int.parse('1');
static int baseS0 = int.parse('1');
static int baseS1 = int.parse('2');
int base0;
double base1;
Object? base2;
@@ -48,10 +49,12 @@ class FieldTestBase {
Float64x2 base4;
FieldTestBase(this.base0, this.base1, this.base2, this.base3, this.base4) {
baseS++;
baseS0++;
baseS1++;
}
String foo() => 'Base.foo: [$baseS, $base0, $base1, $base2, $base3, $base4]';
String foo() =>
'Base.foo: [$baseS0, $baseS1, $base0, $base1, $base2, $base3, $base4]';
}
class FieldTestSub<T> extends FieldTestBase {
+2
View File
@@ -293,6 +293,8 @@ void SnapshotAnalyzer::DumpField(const Field& field) {
js_.PrintProperty64("type_class", GetObjectId(field.type()));
if (field.is_static()) {
js_.PrintProperty("instance", GetObjectId(field.StaticValue()));
js_.PrintProperty64("static_field_offset",
FieldTable::FieldOffsetFor(field.field_id()));
}
if (field.HasInitializerFunction()) {
js_.PrintProperty("initializer_function",