Object allocation
TEST=tools/test.py -n vm-modaot-mac-debug-arm64 language Issue: https://github.com/dart-lang/sdk/issues/61635 Change-Id: Ie569c19ef37e27f7f711dfc3d62db818691f28fd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/476600 Commit-Queue: Alexander Markov <alexmarkov@google.com> Reviewed-by: Slava Egorov <vegorov@google.com>
This commit is contained in:
committed by
Commit Queue
parent
ab311f476c
commit
151bc79032
@@ -12,4 +12,5 @@ extension type CField(ast.Field _raw) {
|
||||
bool get isFinal => _raw.isFinal;
|
||||
bool get hasInitializer => _raw.initializer != null;
|
||||
CType get type => CType.fromStaticType(_raw.type);
|
||||
ast.Class get enclosingClass => _raw.enclosingClass!;
|
||||
}
|
||||
|
||||
@@ -1644,7 +1644,9 @@ abstract base class MoveOp {}
|
||||
enum ParallelMoveStage {
|
||||
// Move fixed output of the instruction to its desired location.
|
||||
output,
|
||||
// Split/spill live ranges.
|
||||
// Spill output of the instruction.
|
||||
spill,
|
||||
// Split live ranges.
|
||||
split,
|
||||
// Moves at control flow edges (including phi moves).
|
||||
control,
|
||||
|
||||
@@ -181,6 +181,7 @@ final class IrToText extends VoidInstructionVisitor {
|
||||
DynamicCallKind.getter => 'get ',
|
||||
DynamicCallKind.setter => 'set ',
|
||||
}}${instr.selector}',
|
||||
AllocateObject() => 'AllocateObject ${instr.type}',
|
||||
BinaryIntOp() => 'BinaryIntOp ${instr.op.token}',
|
||||
UnaryIntOp() => 'UnaryIntOp ${instr.op.token}',
|
||||
BinaryDoubleOp() => 'BinaryDoubleOp ${instr.op.token}',
|
||||
|
||||
@@ -209,7 +209,7 @@ B0 = EntryBlock()
|
||||
B0 = EntryBlock()
|
||||
v13 = Constant(null)
|
||||
v1 = Parameter(a)
|
||||
v2 = AllocateObject()
|
||||
v2 = AllocateObject B()
|
||||
DirectCall B.(v2, v1)
|
||||
v8 = InterfaceCall getter C.y(v2)
|
||||
v10 = InterfaceCall getter C.x(v2)
|
||||
|
||||
@@ -53,7 +53,7 @@ B0 = EntryBlock()
|
||||
B0 = EntryBlock()
|
||||
v1 = TypeParameters()
|
||||
v2 = TypeArguments(v1, <A..T%>)
|
||||
v3 = AllocateObject(v2)
|
||||
v3 = AllocateObject A<A..T%>(v2)
|
||||
DirectCall A._(v3)
|
||||
Return(v3)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:native_compiler/back_end/assembler.dart';
|
||||
import 'package:native_compiler/back_end/code.dart';
|
||||
import 'package:native_compiler/back_end/locations.dart';
|
||||
import 'package:native_compiler/runtime/vm_defs.dart';
|
||||
import 'package:cfg/ir/constant_value.dart';
|
||||
@@ -328,6 +329,49 @@ final class Arm64Assembler extends Assembler with Uint32OutputBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a [base + offset] address for arbitrary offset,
|
||||
/// generating extra code if necessary.
|
||||
/// The resulting address can be used in ldp/stp instructions.
|
||||
Address pairAddress(
|
||||
Register base,
|
||||
int offset, [
|
||||
OperandSize sz = OperandSize.s64,
|
||||
]) {
|
||||
final scale = sz.log2sizeInBytes;
|
||||
if (_isInt(7 + scale, offset) && ((offset & (sz.sizeInBytes - 1)) == 0)) {
|
||||
return RegOffsetAddress(base, offset);
|
||||
} else {
|
||||
throw 'Large address offsets are not implemented yet: $offset';
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void enterDartFrame() {
|
||||
pushPair(FP, LR);
|
||||
mov(FP, stackPointerReg);
|
||||
|
||||
// Tag and save caller pool pointer.
|
||||
add(poolPointerReg, poolPointerReg, Immediate(heapObjectTag));
|
||||
pushPair(poolPointerReg, codeReg);
|
||||
|
||||
// Load and untag current pool pointer.
|
||||
ldr(
|
||||
poolPointerReg,
|
||||
fieldAddress(codeReg, vmOffsets.Code_object_pool_offset),
|
||||
);
|
||||
sub(poolPointerReg, poolPointerReg, Immediate(heapObjectTag));
|
||||
}
|
||||
|
||||
@override
|
||||
void leaveDartFrame() {
|
||||
// Restore and untag pool pointer.
|
||||
ldr(poolPointerReg, RegOffsetAddress(FP, -2 * wordSize));
|
||||
sub(poolPointerReg, poolPointerReg, Immediate(heapObjectTag));
|
||||
|
||||
mov(stackPointerReg, FP);
|
||||
popPair(FP, LR);
|
||||
}
|
||||
|
||||
@override
|
||||
void push(Register reg) {
|
||||
str(
|
||||
@@ -503,6 +547,56 @@ final class Arm64Assembler extends Assembler with Uint32OutputBuffer {
|
||||
bool canEncodeBitMasks(int value, [OperandSize sz = OperandSize.s64]) =>
|
||||
Immediate(value).tryEncodingBitMasks(sz) != null;
|
||||
|
||||
@override
|
||||
void addImmediate(
|
||||
Register dst,
|
||||
Register src,
|
||||
int value, [
|
||||
OperandSize sz = OperandSize.s64,
|
||||
]) {
|
||||
assert(sz.is32or64);
|
||||
assert(_isInt(sz.bitWidth, value) || _isUint(sz.bitWidth, value));
|
||||
if (value == 0) {
|
||||
if (dst != src) {
|
||||
mov(dst, src, sz);
|
||||
}
|
||||
} else if (canEncodeImm12(value)) {
|
||||
add(dst, src, Immediate(value), sz);
|
||||
} else if (canEncodeImm12(-value)) {
|
||||
sub(dst, src, Immediate(-value), sz);
|
||||
} else {
|
||||
assert(src != tempReg);
|
||||
loadImmediate(tempReg, value);
|
||||
if (dst == SP || src == SP) {
|
||||
add(dst, src, ExtRegOperand(tempReg, .UXTX, 0), sz);
|
||||
} else {
|
||||
add(dst, src, tempReg, sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void andImmediate(
|
||||
Register dst,
|
||||
Register src,
|
||||
int value, [
|
||||
OperandSize sz = OperandSize.s64,
|
||||
]) {
|
||||
assert(sz.is32or64);
|
||||
assert(_isInt(sz.bitWidth, value) || _isUint(sz.bitWidth, value));
|
||||
if (value == 0) {
|
||||
movz(dst, 0);
|
||||
} else if (value == -1) {
|
||||
mov(dst, src, sz);
|
||||
} else if (canEncodeBitMasks(value, sz)) {
|
||||
and(dst, src, Immediate(value), sz);
|
||||
} else {
|
||||
assert(src != tempReg);
|
||||
loadImmediate(tempReg, value);
|
||||
and(dst, src, tempReg, sz);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void callRuntime(RuntimeEntry entry, int argumentCount) {
|
||||
ldr(
|
||||
@@ -520,6 +614,18 @@ final class Arm64Assembler extends Assembler with Uint32OutputBuffer {
|
||||
blr(LR);
|
||||
}
|
||||
|
||||
@override
|
||||
void callLeafRuntime(LeafRuntimeEntry entry) {
|
||||
unimplemented("callLeafRuntime $entry");
|
||||
}
|
||||
|
||||
@override
|
||||
void callStub(Code stub) {
|
||||
loadFromPool(codeReg, stub);
|
||||
ldr(LR, fieldAddress(codeReg, vmOffsets.Code_entry_point_offset.first));
|
||||
blr(LR);
|
||||
}
|
||||
|
||||
@override
|
||||
void unimplemented(String message) {
|
||||
loadConstant(R0, ConstantValue.fromString(message));
|
||||
|
||||
@@ -5,10 +5,14 @@
|
||||
import 'package:cfg/ir/constant_value.dart';
|
||||
import 'package:cfg/ir/instructions.dart';
|
||||
import 'package:cfg/utils/misc.dart';
|
||||
import 'package:kernel/ast.dart' as ast;
|
||||
import 'package:native_compiler/back_end/arm64/assembler.dart';
|
||||
import 'package:native_compiler/back_end/arm64/stub_code_generator.dart';
|
||||
import 'package:native_compiler/back_end/assembler.dart';
|
||||
import 'package:native_compiler/back_end/code_generator.dart';
|
||||
import 'package:native_compiler/back_end/locations.dart';
|
||||
import 'package:native_compiler/back_end/object_pool.dart';
|
||||
import 'package:native_compiler/runtime/type_utils.dart';
|
||||
import 'package:native_compiler/runtime/vm_defs.dart';
|
||||
|
||||
final class Arm64CodeGenerator extends CodeGenerator {
|
||||
@@ -21,19 +25,7 @@ final class Arm64CodeGenerator extends CodeGenerator {
|
||||
|
||||
@override
|
||||
void enterFrame() {
|
||||
_asm.pushPair(FP, LR);
|
||||
_asm.mov(FP, stackPointerReg);
|
||||
|
||||
// Tag and save caller pool pointer.
|
||||
_asm.add(poolPointerReg, poolPointerReg, Immediate(heapObjectTag));
|
||||
_asm.pushPair(poolPointerReg, codeReg);
|
||||
|
||||
// Load and untag current pool pointer.
|
||||
_asm.ldr(
|
||||
poolPointerReg,
|
||||
_asm.fieldAddress(codeReg, _asm.vmOffsets.Code_object_pool_offset),
|
||||
);
|
||||
_asm.sub(poolPointerReg, poolPointerReg, Immediate(heapObjectTag));
|
||||
_asm.enterDartFrame();
|
||||
|
||||
// TODO: calculate stack frame size.
|
||||
_asm.sub(stackPointerReg, stackPointerReg, Immediate(64));
|
||||
@@ -185,12 +177,7 @@ final class Arm64CodeGenerator extends CodeGenerator {
|
||||
@override
|
||||
void visitReturn(Return instr) {
|
||||
assert(inputReg(instr, 0) == returnReg);
|
||||
// Restore and untag pool pointer.
|
||||
_asm.ldr(poolPointerReg, RegOffsetAddress(FP, -2 * wordSize));
|
||||
_asm.sub(poolPointerReg, poolPointerReg, Immediate(heapObjectTag));
|
||||
|
||||
_asm.mov(stackPointerReg, FP);
|
||||
_asm.popPair(FP, LR);
|
||||
_asm.leaveDartFrame();
|
||||
_asm.ret();
|
||||
}
|
||||
|
||||
@@ -255,13 +242,13 @@ final class Arm64CodeGenerator extends CodeGenerator {
|
||||
// TODO: call directly through Code.
|
||||
_asm.ldr(
|
||||
codeReg,
|
||||
_asm.fieldAddress(functionReg, _asm.vmOffsets.Function_code_offset),
|
||||
_asm.fieldAddress(functionReg, vmOffsets.Function_code_offset),
|
||||
);
|
||||
_asm.ldr(
|
||||
tempReg,
|
||||
_asm.fieldAddress(
|
||||
functionReg,
|
||||
_asm.vmOffsets.Function_entry_point_offset.first,
|
||||
vmOffsets.Function_entry_point_offset.first,
|
||||
),
|
||||
);
|
||||
_asm.blr(tempReg);
|
||||
@@ -350,7 +337,107 @@ final class Arm64CodeGenerator extends CodeGenerator {
|
||||
|
||||
@override
|
||||
void visitAllocateObject(AllocateObject instr) {
|
||||
_asm.unimplemented('Unimplemented: code generation for AllocateObject');
|
||||
final cls = (instr.type.dartType as ast.InterfaceType).classNode;
|
||||
final instanceSize = objectLayout.getInstanceSize(cls);
|
||||
final typeArgsField = objectLayout.getTypeArgumentsField(cls);
|
||||
final typeArgumentsReg = AllocationStub.typeArgumentsReg;
|
||||
final tagsReg = AllocationStub.tagsReg;
|
||||
final resultReg = AllocationStub.resultReg;
|
||||
assert(!instr.hasTypeArguments || inputReg(instr, 0) == typeArgumentsReg);
|
||||
assert(outputReg(instr) == resultReg);
|
||||
|
||||
// TODO: support huge objects
|
||||
|
||||
final done = Label();
|
||||
Label slowPath = addSlowPath(() {
|
||||
_asm.callStub(backEndState.stubFactory.getAllocationStub(cls));
|
||||
_asm.b(done);
|
||||
});
|
||||
|
||||
final endReg = AllocationStub.scratch1Reg;
|
||||
final newTopReg = AllocationStub.scratch2Reg;
|
||||
// Load Thread.top_ and Thread.end_.
|
||||
_asm.ldp(
|
||||
resultReg,
|
||||
endReg,
|
||||
_asm.pairAddress(threadReg, vmOffsets.Thread_top_offset),
|
||||
);
|
||||
_asm.addImmediate(newTopReg, resultReg, instanceSize);
|
||||
_asm.cmp(endReg, newTopReg);
|
||||
_asm.b(slowPath, Condition.unsignedLessOrEqual);
|
||||
|
||||
// TLAB has enough space. Update top and initialize object.
|
||||
_asm.loadFromPool(tagsReg, NewObjectTags(cls));
|
||||
_asm.str(newTopReg, _asm.address(threadReg, vmOffsets.Thread_top_offset));
|
||||
_asm.str(tagsReg, _asm.address(resultReg, vmOffsets.Object_tags_offset));
|
||||
// TODO: figure out if we need store-store barrier here.
|
||||
|
||||
// TODO: support compressed pointers.
|
||||
const maxUnrolledSize = 16 * wordSize;
|
||||
if (instanceSize <= maxUnrolledSize) {
|
||||
int offset = vmOffsets.Instance_first_field_offset;
|
||||
for (; offset + 2 * wordSize <= instanceSize; offset += 2 * wordSize) {
|
||||
_asm.stp(nullReg, nullReg, _asm.pairAddress(resultReg, offset));
|
||||
}
|
||||
if (offset < instanceSize) {
|
||||
_asm.str(nullReg, _asm.address(resultReg, offset));
|
||||
offset += wordSize;
|
||||
}
|
||||
assert(offset == instanceSize);
|
||||
} else {
|
||||
final fieldReg = AllocationStub.scratch1Reg;
|
||||
_asm.addImmediate(
|
||||
fieldReg,
|
||||
resultReg,
|
||||
vmOffsets.Instance_first_field_offset,
|
||||
);
|
||||
|
||||
final loop = Label();
|
||||
_asm.bind(loop);
|
||||
_asm.stp(
|
||||
nullReg,
|
||||
nullReg,
|
||||
WritebackRegOffsetAddress(fieldReg, 2 * wordSize, isPostIndexed: true),
|
||||
);
|
||||
// There is at least two word (kAllocationRedZoneSize) gap at the end of page
|
||||
// which makes it possible to initialize objects by two words at once and
|
||||
// write slightly beyond the end.
|
||||
_asm.cmp(fieldReg, newTopReg);
|
||||
_asm.b(loop, Condition.unsignedLess);
|
||||
}
|
||||
|
||||
_asm.addImmediate(resultReg, resultReg, heapObjectTag);
|
||||
|
||||
if (typeArgsField != null) {
|
||||
if (instr.hasTypeArguments) {
|
||||
_asm.str(
|
||||
typeArgumentsReg,
|
||||
_asm.fieldAddress(
|
||||
resultReg,
|
||||
objectLayout.getFieldOffset(typeArgsField),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
final typeArgs = getInstantiatorTypeArguments(cls, []);
|
||||
if (typeArgs != null) {
|
||||
_asm.loadConstant(
|
||||
typeArgumentsReg,
|
||||
ConstantValue(TypeArgumentsConstant(typeArgs)),
|
||||
);
|
||||
_asm.str(
|
||||
typeArgumentsReg,
|
||||
_asm.fieldAddress(
|
||||
resultReg,
|
||||
objectLayout.getFieldOffset(typeArgsField),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: allocation profile; allocation probe points.
|
||||
|
||||
_asm.bind(done);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -395,11 +482,32 @@ final class Arm64CodeGenerator extends CodeGenerator {
|
||||
|
||||
@override
|
||||
void generateMove(Location from, Location to) {
|
||||
if (from is Register && to is Register) {
|
||||
_asm.mov(to, from);
|
||||
return;
|
||||
switch (from) {
|
||||
case Register():
|
||||
switch (to) {
|
||||
case Register():
|
||||
_asm.mov(to, from);
|
||||
return;
|
||||
case StackLocation():
|
||||
_asm.str(from, _asm.address(FP, to.frameOffset));
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case StackLocation():
|
||||
switch (to) {
|
||||
case Register():
|
||||
_asm.ldr(to, _asm.address(FP, from.frameOffset));
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_asm.unimplemented('Unimplemented: code generation for generateMove');
|
||||
_asm.unimplemented(
|
||||
'Unimplemented: code generation for generateMove ${from.runtimeType} -> ${to.runtimeType}',
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -445,3 +553,7 @@ extension on ComparisonOpcode {
|
||||
ComparisonOpcode.doubleGreaterOrEqual => Condition.greaterOrEqual,
|
||||
};
|
||||
}
|
||||
|
||||
extension on StackLocation {
|
||||
int get frameOffset => -(2 + index) * wordSize;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:native_compiler/back_end/arm64/assembler.dart';
|
||||
import 'package:native_compiler/back_end/arm64/stub_code_generator.dart';
|
||||
import 'package:native_compiler/back_end/constraints.dart';
|
||||
import 'package:native_compiler/back_end/locations.dart';
|
||||
import 'package:cfg/ir/instructions.dart';
|
||||
@@ -190,9 +191,16 @@ final class Arm64Constraints extends Constraints {
|
||||
|
||||
@override
|
||||
InstructionConstraints? visitAllocateObject(AllocateObject instr) =>
|
||||
InstructionConstraints(anyCpuRegister, [
|
||||
if (instr.inputCount == 1) anyCpuRegister,
|
||||
]);
|
||||
InstructionConstraints(
|
||||
AllocationStub.resultReg,
|
||||
[if (instr.hasTypeArguments) AllocationStub.typeArgumentsReg],
|
||||
[
|
||||
if (!instr.hasTypeArguments) AllocationStub.typeArgumentsReg,
|
||||
AllocationStub.tagsReg,
|
||||
AllocationStub.scratch1Reg,
|
||||
AllocationStub.scratch2Reg,
|
||||
],
|
||||
);
|
||||
|
||||
@override
|
||||
InstructionConstraints? visitAllocateClosure(AllocateClosure instr) =>
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright (c) 2026 the Dart 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.
|
||||
|
||||
import 'package:cfg/ir/constant_value.dart';
|
||||
import 'package:kernel/ast.dart' as ast show Class;
|
||||
import 'package:native_compiler/back_end/arm64/assembler.dart';
|
||||
import 'package:native_compiler/back_end/assembler.dart';
|
||||
import 'package:native_compiler/back_end/locations.dart';
|
||||
import 'package:native_compiler/back_end/stub_code_generator.dart';
|
||||
import 'package:native_compiler/runtime/type_utils.dart';
|
||||
import 'package:native_compiler/runtime/vm_defs.dart';
|
||||
|
||||
abstract base class Arm64StubCodeGenerator implements StubCodeGenerator {
|
||||
final Arm64Assembler _asm;
|
||||
|
||||
Arm64StubCodeGenerator(VMOffsets vmOffsets)
|
||||
: _asm = Arm64Assembler(vmOffsets);
|
||||
|
||||
void _generate();
|
||||
|
||||
void enterStubFrame() {
|
||||
_asm.enterDartFrame();
|
||||
}
|
||||
|
||||
void leaveStubFrame() {
|
||||
_asm.leaveDartFrame();
|
||||
}
|
||||
|
||||
@override
|
||||
Assembler generate() {
|
||||
_generate();
|
||||
return _asm;
|
||||
}
|
||||
}
|
||||
|
||||
final class AllocationStub extends Arm64StubCodeGenerator {
|
||||
static const Register resultReg = R0;
|
||||
static const Register typeArgumentsReg = R1;
|
||||
static const Register tagsReg = R2;
|
||||
|
||||
static const Register scratch1Reg = R3;
|
||||
static const Register scratch2Reg = R4;
|
||||
|
||||
final ast.Class cls;
|
||||
|
||||
AllocationStub(super.vmOffsets, this.cls);
|
||||
|
||||
@override
|
||||
void _generate() {
|
||||
enterStubFrame();
|
||||
|
||||
if (cls.typeParameters.isEmpty) {
|
||||
final typeArgs = hasInstantiatorTypeArguments(cls)
|
||||
? getInstantiatorTypeArguments(cls, [])
|
||||
: null;
|
||||
if (typeArgs == null) {
|
||||
_asm.mov(typeArgumentsReg, nullReg);
|
||||
} else {
|
||||
_asm.loadConstant(
|
||||
typeArgumentsReg,
|
||||
ConstantValue(TypeArgumentsConstant(typeArgs)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_generateRuntimeCall();
|
||||
|
||||
leaveStubFrame();
|
||||
_asm.ret();
|
||||
}
|
||||
|
||||
void _generateRuntimeCall() {
|
||||
_asm.loadFromPool(scratch1Reg, cls);
|
||||
|
||||
// Space for result.
|
||||
_asm.push(nullReg);
|
||||
// Class and type arguments.
|
||||
_asm.pushPair(typeArgumentsReg, scratch1Reg);
|
||||
_asm.callRuntime(RuntimeEntry.AllocateObject, 2);
|
||||
|
||||
_asm.ldr(resultReg, _asm.address(stackPointerReg, 2 * wordSize));
|
||||
|
||||
// TODO: EnsureIsNewOrRemembered after write barrier elimination is implemented.
|
||||
}
|
||||
}
|
||||
|
||||
final class Arm64StubFactory extends StubFactory {
|
||||
final VMOffsets vmOffsets;
|
||||
Arm64StubFactory(this.vmOffsets, super.consumeGeneratedCode);
|
||||
|
||||
@override
|
||||
StubCodeGenerator allocationStubGenerator(ast.Class cls) =>
|
||||
AllocationStub(vmOffsets, cls);
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:native_compiler/back_end/code.dart';
|
||||
import 'package:native_compiler/back_end/locations.dart';
|
||||
import 'package:native_compiler/back_end/object_pool.dart';
|
||||
import 'package:native_compiler/runtime/vm_defs.dart';
|
||||
@@ -132,6 +133,9 @@ abstract base class Assembler {
|
||||
Address fieldAddress(Register obj, int offset) =>
|
||||
address(obj, offset - heapObjectTag);
|
||||
|
||||
void enterDartFrame();
|
||||
void leaveDartFrame();
|
||||
|
||||
// Push and pop values using Dart stackPointerReg.
|
||||
void push(Register reg);
|
||||
void pop(Register reg);
|
||||
@@ -149,7 +153,25 @@ abstract base class Assembler {
|
||||
/// Load arbitrary integer [value] into register.
|
||||
void loadImmediate(Register reg, int value);
|
||||
|
||||
/// [dst] = [src] + arbitrary integer [value].
|
||||
void addImmediate(
|
||||
Register dst,
|
||||
Register src,
|
||||
int value, [
|
||||
OperandSize sz = OperandSize.s64,
|
||||
]);
|
||||
|
||||
/// [dst] = bitwise and ([src], arbitrary integer [value]).
|
||||
void andImmediate(
|
||||
Register dst,
|
||||
Register src,
|
||||
int value, [
|
||||
OperandSize sz = OperandSize.s64,
|
||||
]);
|
||||
|
||||
void callRuntime(RuntimeEntry entry, int argumentCount);
|
||||
void callLeafRuntime(LeafRuntimeEntry entry);
|
||||
void callStub(Code stub);
|
||||
|
||||
void unimplemented(String message);
|
||||
}
|
||||
|
||||
@@ -3,15 +3,24 @@
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:cfg/ir/instructions.dart';
|
||||
import 'package:native_compiler/back_end/code_generator.dart';
|
||||
import 'package:native_compiler/back_end/code.dart';
|
||||
import 'package:native_compiler/back_end/locations.dart';
|
||||
import 'package:native_compiler/back_end/stub_code_generator.dart';
|
||||
import 'package:native_compiler/runtime/object_layout.dart';
|
||||
import 'package:native_compiler/runtime/vm_defs.dart';
|
||||
|
||||
/// Hold back-end state shared between code generation
|
||||
/// and register allocation.
|
||||
class BackEndState {
|
||||
/// Runtime offsets and constants.
|
||||
late final VMOffsets vmOffsets;
|
||||
|
||||
/// Layout of Dart objects.
|
||||
late final ObjectLayout objectLayout;
|
||||
|
||||
/// Reusable stubs.
|
||||
late final StubFactory stubFactory;
|
||||
|
||||
/// Block order for the code generation.
|
||||
late final List<Block> codeGenBlockOrder;
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2026, the Dart 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.
|
||||
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:cfg/ir/functions.dart';
|
||||
import 'package:native_compiler/back_end/object_pool.dart';
|
||||
|
||||
/// Generated code for a function or a stub.
|
||||
class Code {
|
||||
final CFunction? function;
|
||||
final Uint8List instructions;
|
||||
final ObjectPool objectPool;
|
||||
|
||||
/// Offset of instructions in the resulting image.
|
||||
int? instructionsImageOffset;
|
||||
|
||||
Code(this.function, this.instructions, this.objectPool);
|
||||
}
|
||||
|
||||
/// Comsumer of the generated code.
|
||||
typedef CodeConsumer = void Function(Code);
|
||||
@@ -5,29 +5,15 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:cfg/ir/constant_value.dart';
|
||||
import 'package:cfg/ir/functions.dart';
|
||||
import 'package:cfg/ir/instructions.dart';
|
||||
import 'package:cfg/ir/visitor.dart';
|
||||
import 'package:cfg/passes/pass.dart';
|
||||
import 'package:native_compiler/back_end/assembler.dart';
|
||||
import 'package:native_compiler/back_end/back_end_state.dart';
|
||||
import 'package:native_compiler/back_end/code.dart';
|
||||
import 'package:native_compiler/back_end/locations.dart';
|
||||
import 'package:native_compiler/back_end/object_pool.dart';
|
||||
|
||||
/// Generated code for a function.
|
||||
class Code {
|
||||
final CFunction function;
|
||||
final Uint8List instructions;
|
||||
final ObjectPool objectPool;
|
||||
|
||||
/// Offset of instructions in the resulting image.
|
||||
int? instructionsImageOffset;
|
||||
|
||||
Code(this.function, this.instructions, this.objectPool);
|
||||
}
|
||||
|
||||
/// Comsumer of the generated code.
|
||||
typedef CodeConsumer = void Function(Code);
|
||||
import 'package:native_compiler/runtime/object_layout.dart';
|
||||
import 'package:native_compiler/runtime/vm_defs.dart';
|
||||
|
||||
/// Base class for architecture-specific code generator.
|
||||
///
|
||||
@@ -53,8 +39,13 @@ abstract base class CodeGenerator extends Pass
|
||||
(i) => Label(),
|
||||
);
|
||||
|
||||
/// Slow paths generated after all blocks.
|
||||
final List<SlowPath> _slowPaths = [];
|
||||
|
||||
CodeGenerator(this.backEndState) : super('CodeGen');
|
||||
|
||||
VMOffsets get vmOffsets => backEndState.vmOffsets;
|
||||
ObjectLayout get objectLayout => backEndState.objectLayout;
|
||||
List<Block> get codeGenBlockOrder => backEndState.codeGenBlockOrder;
|
||||
|
||||
Location loc(OperandId operandId) =>
|
||||
@@ -108,6 +99,11 @@ abstract base class CodeGenerator extends Pass
|
||||
}
|
||||
_currentBlockIndex = -1;
|
||||
|
||||
for (final slowPath in _slowPaths) {
|
||||
_asm.bind(slowPath.entry);
|
||||
slowPath.generator();
|
||||
}
|
||||
|
||||
backEndState.consumeGeneratedCode(
|
||||
Code(graph.function, _asm.bytes, _asm.objectPool),
|
||||
);
|
||||
@@ -164,6 +160,12 @@ abstract base class CodeGenerator extends Pass
|
||||
return firstNonEmpty;
|
||||
}
|
||||
|
||||
Label addSlowPath(void Function() generator) {
|
||||
final entry = Label();
|
||||
_slowPaths.add(SlowPath(entry, generator));
|
||||
return entry;
|
||||
}
|
||||
|
||||
@override
|
||||
void visitEntryBlock(EntryBlock instr) {}
|
||||
|
||||
@@ -202,24 +204,33 @@ abstract base class CodeGenerator extends Pass
|
||||
// TODO: merge subsequent ParallelMove instructions.
|
||||
final map = <Location, Location>{};
|
||||
for (final move in instr.moves) {
|
||||
if (move is Move && move.from != move.to) {
|
||||
assert(!map.containsKey(move.from));
|
||||
map[move.from] = move.to;
|
||||
if (move is Move) {
|
||||
final from = move.from.physicalLocation;
|
||||
final to = move.to.physicalLocation;
|
||||
if (from != to) {
|
||||
assert(!map.containsKey(from));
|
||||
map[from] = to;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final move in instr.moves) {
|
||||
if (move is Move && map.containsKey(move.from)) {
|
||||
if (map.containsKey(move.to)) {
|
||||
_generateDependentMoves(move.from, move.to, map);
|
||||
} else {
|
||||
generateMove(move.from, move.to);
|
||||
map.remove(move.from);
|
||||
if (move is Move) {
|
||||
final from = move.from.physicalLocation;
|
||||
final to = move.to.physicalLocation;
|
||||
|
||||
if (map.containsKey(from)) {
|
||||
if (map.containsKey(to)) {
|
||||
_generateDependentMoves(from, to, map);
|
||||
} else {
|
||||
generateMove(from, to);
|
||||
map.remove(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final move in instr.moves) {
|
||||
if (move is LoadConstant) {
|
||||
generateLoadConstant(move.value, move.to);
|
||||
generateLoadConstant(move.value, move.to.physicalLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -280,3 +291,9 @@ abstract base class CodeGenerator extends Pass
|
||||
void visitStringInterpolation(StringInterpolation instr) =>
|
||||
throw 'Unexpected StringInterpolation (should be lowered)';
|
||||
}
|
||||
|
||||
class SlowPath {
|
||||
final Label entry;
|
||||
final void Function() generator;
|
||||
SlowPath(this.entry, this.generator);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
// 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.
|
||||
|
||||
import 'package:kernel/ast.dart' as ast;
|
||||
|
||||
/// Helper class for building object pool accessible from generated code.
|
||||
///
|
||||
/// TODO: add tags, different kinds of entries.
|
||||
class ObjectPool {
|
||||
final List<Object> entries = [];
|
||||
final Map<Object, int> _objects = {};
|
||||
@@ -17,3 +17,20 @@ class ObjectPool {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
/// Base class for specialized object pool entries which are not just
|
||||
/// object references.
|
||||
sealed class SpecializedEntry {}
|
||||
|
||||
/// Object pool entry representing tags for the new objects of the given class.
|
||||
final class NewObjectTags extends SpecializedEntry {
|
||||
final ast.Class cls;
|
||||
NewObjectTags(this.cls);
|
||||
|
||||
@override
|
||||
int get hashCode => cls.hashCode + 19;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
other is NewObjectTags && this.cls == other.cls;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ final class LinearScanRegisterAllocator extends RegisterAllocator {
|
||||
// which can be inserted later between instructions.
|
||||
static const int step = 2;
|
||||
|
||||
static const bool trace = false;
|
||||
static const bool trace = const bool.fromEnvironment('trace.regalloc');
|
||||
|
||||
static const int maxPosition = 0x7fffffff;
|
||||
|
||||
@@ -818,7 +818,7 @@ final class LinearScanRegisterAllocator extends RegisterAllocator {
|
||||
if (liveRange.allocatedLocation is! StackLocation) {
|
||||
_insertMoveBefore(
|
||||
_nextInstruction(instr),
|
||||
ParallelMoveStage.split,
|
||||
ParallelMoveStage.spill,
|
||||
liveRange.allocatedLocation!,
|
||||
spillSlot,
|
||||
);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2026, the Dart 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.
|
||||
|
||||
import 'package:kernel/ast.dart' as ast show Class;
|
||||
import 'package:native_compiler/back_end/assembler.dart';
|
||||
import 'package:native_compiler/back_end/code.dart';
|
||||
|
||||
/// Interface class for architecture-specific stub code generator.
|
||||
abstract interface class StubCodeGenerator {
|
||||
Assembler generate();
|
||||
}
|
||||
|
||||
/// Base class for architecture-specific stub factory.
|
||||
///
|
||||
/// Generates and caches stubs on demand.
|
||||
abstract base class StubFactory {
|
||||
final CodeConsumer consumeGeneratedCode;
|
||||
Map<ast.Class, Code> _allocationStubs = {};
|
||||
|
||||
StubFactory(this.consumeGeneratedCode);
|
||||
|
||||
StubCodeGenerator allocationStubGenerator(ast.Class cls);
|
||||
|
||||
Code _generateCode(StubCodeGenerator generator) {
|
||||
final asm = generator.generate();
|
||||
final code = Code(null, asm.bytes, asm.objectPool);
|
||||
consumeGeneratedCode(code);
|
||||
return code;
|
||||
}
|
||||
|
||||
Code getAllocationStub(ast.Class cls) =>
|
||||
_allocationStubs[cls] ??= _generateCode(allocationStubGenerator(cls));
|
||||
}
|
||||
@@ -7,7 +7,8 @@ import 'package:cfg/front_end/recognized_methods.dart';
|
||||
import 'package:cfg/ir/flow_graph.dart';
|
||||
import 'package:cfg/ir/functions.dart';
|
||||
import 'package:kernel/ast.dart' as ast;
|
||||
import 'package:native_compiler/back_end/code_generator.dart';
|
||||
import 'package:native_compiler/back_end/code.dart';
|
||||
import 'package:native_compiler/back_end/stub_code_generator.dart';
|
||||
import 'package:native_compiler/configuration.dart';
|
||||
import 'package:native_compiler/snapshot/image_writer.dart';
|
||||
import 'package:native_compiler/snapshot/snapshot.dart';
|
||||
@@ -21,10 +22,12 @@ class CompilationSet {
|
||||
final List<CFunction> _pendingFunctions = [];
|
||||
final ImageWriter _imageWriter;
|
||||
late final SnapshotSerializer _snapshot;
|
||||
late final StubFactory _stubFactory;
|
||||
|
||||
CompilationSet(this.libraries, this.config)
|
||||
: _imageWriter = config.createImageWriter() {
|
||||
_snapshot = SnapshotSerializer(config.targetCPU, functionRegistry);
|
||||
_stubFactory = config.createStubFactory(_consumeGeneratedCode);
|
||||
}
|
||||
|
||||
/// Add [function] to be compiled.
|
||||
@@ -111,7 +114,9 @@ class CompilationSet {
|
||||
rethrow;
|
||||
}
|
||||
|
||||
config.createPipeline(functionRegistry, _consumeGeneratedCode).run(graph);
|
||||
config
|
||||
.createPipeline(functionRegistry, _stubFactory, _consumeGeneratedCode)
|
||||
.run(graph);
|
||||
}
|
||||
|
||||
void _consumeGeneratedCode(Code code) {
|
||||
|
||||
@@ -11,13 +11,17 @@ import 'package:cfg/passes/simplification.dart';
|
||||
import 'package:cfg/passes/value_numbering.dart';
|
||||
import 'package:native_compiler/back_end/arm64/code_generator.dart';
|
||||
import 'package:native_compiler/back_end/arm64/constraints.dart';
|
||||
import 'package:native_compiler/back_end/arm64/stub_code_generator.dart';
|
||||
import 'package:native_compiler/back_end/back_end_state.dart';
|
||||
import 'package:native_compiler/back_end/code.dart';
|
||||
import 'package:native_compiler/back_end/code_generator.dart';
|
||||
import 'package:native_compiler/back_end/constraints.dart';
|
||||
import 'package:native_compiler/back_end/regalloc_checker.dart';
|
||||
import 'package:native_compiler/back_end/register_allocator.dart';
|
||||
import 'package:native_compiler/back_end/stub_code_generator.dart';
|
||||
import 'package:native_compiler/passes/lowering.dart';
|
||||
import 'package:native_compiler/passes/reorder_blocks.dart';
|
||||
import 'package:native_compiler/runtime/object_layout.dart';
|
||||
import 'package:native_compiler/runtime/vm_defs.dart';
|
||||
import 'package:native_compiler/snapshot/image_writer.dart';
|
||||
import 'package:native_compiler/snapshot/macho/macho_image_writer.dart';
|
||||
@@ -51,8 +55,13 @@ abstract base class Configuration {
|
||||
required this.outputLibraryName,
|
||||
});
|
||||
|
||||
VMOffsets get vmOffsets;
|
||||
|
||||
ObjectLayout get objectLayout;
|
||||
|
||||
Pipeline createPipeline(
|
||||
FunctionRegistry functionRegistry,
|
||||
StubFactory stubFactory,
|
||||
CodeConsumer consumeGeneratedCode,
|
||||
);
|
||||
|
||||
@@ -65,6 +74,11 @@ abstract base class Configuration {
|
||||
TargetCPU.arm64 => Arm64CodeGenerator(backEndState),
|
||||
};
|
||||
|
||||
StubFactory createStubFactory(CodeConsumer consumeGeneratedCode) =>
|
||||
switch (targetCPU) {
|
||||
TargetCPU.arm64 => Arm64StubFactory(vmOffsets, consumeGeneratedCode),
|
||||
};
|
||||
|
||||
ImageWriter createImageWriter() => switch (imageFormat) {
|
||||
ImageFormat.macho => MachoImageWriter(targetCPU, outputLibraryName),
|
||||
};
|
||||
@@ -78,17 +92,30 @@ final class DevelopmentCompilerConfiguration extends Configuration {
|
||||
required super.outputLibraryName,
|
||||
});
|
||||
|
||||
VMOffsets createVMOffsets() => switch (targetCPU) {
|
||||
@override
|
||||
late final VMOffsets vmOffsets = switch (targetCPU) {
|
||||
TargetCPU.arm64 => Arm64VMOffsets(),
|
||||
};
|
||||
|
||||
@override
|
||||
late final ObjectLayout objectLayout = switch (targetCPU) {
|
||||
TargetCPU.arm64 => ObjectLayout(
|
||||
vmOffsets,
|
||||
wordSize: 8,
|
||||
compressedWordSize: 8,
|
||||
),
|
||||
};
|
||||
|
||||
@override
|
||||
Pipeline createPipeline(
|
||||
FunctionRegistry functionRegistry,
|
||||
StubFactory stubFactory,
|
||||
CodeConsumer consumeGeneratedCode,
|
||||
) {
|
||||
final backEndState = BackEndState();
|
||||
backEndState.vmOffsets = createVMOffsets();
|
||||
backEndState.vmOffsets = vmOffsets;
|
||||
backEndState.objectLayout = objectLayout;
|
||||
backEndState.stubFactory = stubFactory;
|
||||
backEndState.consumeGeneratedCode = consumeGeneratedCode;
|
||||
final constraints = createConstraints();
|
||||
return Pipeline([
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
// Copyright (c) 2026, the Dart 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.
|
||||
|
||||
import 'package:cfg/ir/field.dart';
|
||||
import 'package:cfg/ir/global_context.dart';
|
||||
import 'package:cfg/utils/misc.dart';
|
||||
import 'package:kernel/ast.dart' as ast;
|
||||
import 'package:native_compiler/runtime/vm_defs.dart';
|
||||
|
||||
/// Computes layout of Dart objects (field offsets and instance size).
|
||||
class ObjectLayout {
|
||||
final VMOffsets vmOffsets;
|
||||
final int wordSize;
|
||||
final int compressedWordSize;
|
||||
|
||||
/// Instance size before rounding.
|
||||
final Map<ast.Class, int> _instanceSize = {};
|
||||
|
||||
/// Name of the implicit type arguments field.
|
||||
late final ast.Name _typeArgumentsFieldName = ast.Name('#typeArguments');
|
||||
|
||||
/// Implicit type arguments field for a class.
|
||||
final Map<ast.Class, CField> _typeArgumentsField = {};
|
||||
|
||||
/// Field offsets.
|
||||
final Map<CField, int> _fieldOffset = {};
|
||||
|
||||
ObjectLayout(
|
||||
this.vmOffsets, {
|
||||
required this.wordSize,
|
||||
required this.compressedWordSize,
|
||||
});
|
||||
|
||||
int getInstanceSize(ast.Class cls) {
|
||||
_ensureComputed(cls);
|
||||
return roundUp(_instanceSize[cls]!, objectAlignment(wordSize));
|
||||
}
|
||||
|
||||
int getFieldOffset(CField field) {
|
||||
assert(!field.isStatic);
|
||||
_ensureComputed(field.enclosingClass);
|
||||
return _fieldOffset[field]!;
|
||||
}
|
||||
|
||||
bool isUnboxedField(CField field) {
|
||||
// TODO: support unboxed fields.
|
||||
return false;
|
||||
}
|
||||
|
||||
CField? getTypeArgumentsField(ast.Class cls) {
|
||||
_ensureComputed(cls);
|
||||
return _typeArgumentsField[cls];
|
||||
}
|
||||
|
||||
bool _isComputed(ast.Class cls) => _instanceSize.containsKey(cls);
|
||||
|
||||
void _ensureComputed(ast.Class cls) {
|
||||
if (!_isComputed(cls)) {
|
||||
_computeLayout(cls);
|
||||
}
|
||||
}
|
||||
|
||||
void _computeLayout(ast.Class cls) {
|
||||
if (_computeLayoutOfBuiltInClass(cls)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final superclass = cls.superclass;
|
||||
if (superclass != null) {
|
||||
_ensureComputed(superclass);
|
||||
}
|
||||
|
||||
int nextOffset = _instanceSize[superclass]!;
|
||||
|
||||
final superTypeArgs = superclass != null
|
||||
? _typeArgumentsField[superclass]
|
||||
: null;
|
||||
if (superTypeArgs != null) {
|
||||
// Inherit type arguments field from generic superclass.
|
||||
_typeArgumentsField[cls] = superTypeArgs;
|
||||
} else if (cls.typeParameters.isNotEmpty) {
|
||||
// This class is generic but superclass is not, so
|
||||
// introduce a new implicit type arguments field.
|
||||
final typeArgs = CField(
|
||||
ast.Field.immutable(
|
||||
_typeArgumentsFieldName,
|
||||
isFinal: true,
|
||||
isStatic: false,
|
||||
fileUri: ast.dummyUri,
|
||||
)..parent = cls,
|
||||
);
|
||||
_typeArgumentsField[cls] = typeArgs;
|
||||
_fieldOffset[typeArgs] = nextOffset;
|
||||
nextOffset += compressedWordSize;
|
||||
}
|
||||
|
||||
for (final field in cls.fields) {
|
||||
if (!field.isStatic) {
|
||||
_fieldOffset[CField(field)] = nextOffset;
|
||||
nextOffset += compressedWordSize;
|
||||
}
|
||||
}
|
||||
|
||||
_instanceSize[cls] = nextOffset;
|
||||
}
|
||||
|
||||
late final Map<String, int> _dartCoreInstanceSize = {
|
||||
'_Double': vmOffsets.Double_InstanceSize,
|
||||
'_GrowableList': vmOffsets.GrowableObjectArray_InstanceSize,
|
||||
'_Mint': vmOffsets.Mint_InstanceSize,
|
||||
'_WeakProperty': vmOffsets.WeakProperty_InstanceSize,
|
||||
'_WeakReference': vmOffsets.WeakReference_InstanceSize,
|
||||
'Object': vmOffsets.Instance_InstanceSize,
|
||||
};
|
||||
|
||||
late final Map<String, int> _dartTypedDataInstanceSize = {
|
||||
'_Int32x4': vmOffsets.Int32x4_InstanceSize,
|
||||
'_Float32x4': vmOffsets.Float32x4_InstanceSize,
|
||||
'_Float64x2': vmOffsets.Float64x2_InstanceSize,
|
||||
// TODO: add other built-in classes from dart:typed_data
|
||||
};
|
||||
|
||||
late final Map<String, int> _dartCompactHashInstanceSize = {
|
||||
'_HashVMBase': vmOffsets.LinkedHashBase_InstanceSize,
|
||||
};
|
||||
|
||||
late final ast.Library _typedDataLibrary = GlobalContext
|
||||
.instance
|
||||
.coreTypes
|
||||
.index
|
||||
.getLibrary('dart:typed_data');
|
||||
late final ast.Library _compactHashLibrary = GlobalContext
|
||||
.instance
|
||||
.coreTypes
|
||||
.index
|
||||
.getLibrary('dart:_compact_hash');
|
||||
|
||||
bool _computeLayoutOfBuiltInClass(ast.Class cls) {
|
||||
final library = cls.enclosingLibrary;
|
||||
if (!library.importUri.isScheme('dart')) {
|
||||
return false;
|
||||
}
|
||||
int? size;
|
||||
if (library == GlobalContext.instance.coreTypes.coreLibrary) {
|
||||
size = _dartCoreInstanceSize[cls.name];
|
||||
} else if (library == _typedDataLibrary) {
|
||||
size = _dartTypedDataInstanceSize[cls.name];
|
||||
} else if (library == _compactHashLibrary) {
|
||||
size = _dartCompactHashInstanceSize[cls.name];
|
||||
}
|
||||
// TODO: add built-in classes from dart:ffi
|
||||
if (size != null) {
|
||||
_instanceSize[cls] = size;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -107,6 +107,7 @@ base class VMOffsets {
|
||||
int get ICData_entries_offset => throw 'Unknown';
|
||||
int get ICData_owner_offset => throw 'Unknown';
|
||||
int get ICData_state_bits_offset => throw 'Unknown';
|
||||
int get Instance_first_field_offset => throw 'Unknown';
|
||||
int get Int32x4_value_offset => throw 'Unknown';
|
||||
int get Isolate_finalizers_offset => throw 'Unknown';
|
||||
int get Isolate_has_resumption_breakpoints_offset => throw 'Unknown';
|
||||
@@ -130,6 +131,7 @@ base class VMOffsets {
|
||||
int get NativeArguments_argv_offset => throw 'Unknown';
|
||||
int get NativeArguments_retval_offset => throw 'Unknown';
|
||||
int get NativeArguments_thread_offset => throw 'Unknown';
|
||||
int get Object_tags_offset => throw 'Unknown';
|
||||
int get ObjectStore_double_type_offset => throw 'Unknown';
|
||||
int get ObjectStore_int_type_offset => throw 'Unknown';
|
||||
int get ObjectStore_record_field_names_offset => throw 'Unknown';
|
||||
@@ -752,6 +754,8 @@ final class Arm64VMOffsets extends VMOffsets {
|
||||
@override
|
||||
int get ICData_state_bits_offset => 0x34;
|
||||
@override
|
||||
int get Instance_first_field_offset => 0x8;
|
||||
@override
|
||||
int get Int32x4_value_offset => 0x8;
|
||||
@override
|
||||
int get Isolate_finalizers_offset => 0x18;
|
||||
@@ -798,6 +802,8 @@ final class Arm64VMOffsets extends VMOffsets {
|
||||
@override
|
||||
int get NativeArguments_thread_offset => 0x0;
|
||||
@override
|
||||
int get Object_tags_offset => 0x0;
|
||||
@override
|
||||
int get ObjectStore_double_type_offset => 0x1b0;
|
||||
@override
|
||||
int get ObjectStore_int_type_offset => 0x160;
|
||||
@@ -1661,6 +1667,8 @@ final class Arm64ProductVMOffsets extends VMOffsets {
|
||||
@override
|
||||
int get ICData_state_bits_offset => 0x34;
|
||||
@override
|
||||
int get Instance_first_field_offset => 0x8;
|
||||
@override
|
||||
int get Int32x4_value_offset => 0x8;
|
||||
@override
|
||||
int get Isolate_finalizers_offset => 0x18;
|
||||
@@ -1705,6 +1713,8 @@ final class Arm64ProductVMOffsets extends VMOffsets {
|
||||
@override
|
||||
int get NativeArguments_thread_offset => 0x0;
|
||||
@override
|
||||
int get Object_tags_offset => 0x0;
|
||||
@override
|
||||
int get ObjectStore_double_type_offset => 0x1b0;
|
||||
@override
|
||||
int get ObjectStore_int_type_offset => 0x160;
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'dart:typed_data';
|
||||
import 'package:cfg/ir/constant_value.dart';
|
||||
import 'package:cfg/ir/global_context.dart';
|
||||
import 'package:kernel/ast.dart' as ast;
|
||||
import 'package:native_compiler/back_end/code_generator.dart' show Code;
|
||||
import 'package:native_compiler/back_end/code.dart';
|
||||
import 'package:native_compiler/back_end/object_pool.dart';
|
||||
import 'package:native_compiler/configuration.dart';
|
||||
import 'package:cfg/ir/functions.dart';
|
||||
@@ -81,6 +81,12 @@ enum FunctionKind {
|
||||
fieldInitializer,
|
||||
}
|
||||
|
||||
/// Object pool entry kinds in the module snapshots.
|
||||
///
|
||||
/// This enum should match ModuleSnapshot::ObjectPoolEntryKind
|
||||
/// enum declared in runtime/vm/module_snapshot.cc.
|
||||
enum ObjectPoolEntryKind { objectRef, newObjectTags }
|
||||
|
||||
abstract base class SerializationCluster {
|
||||
/// Add [object] to the cluster and push its outgoing references.
|
||||
void trace(SnapshotSerializer serializer, Object object);
|
||||
@@ -717,7 +723,14 @@ final class ObjectPoolSerializationCluster extends SerializationCluster {
|
||||
final pool = object as ObjectPool;
|
||||
_objects.add(pool);
|
||||
for (final entry in pool.entries) {
|
||||
serializer.push(entry);
|
||||
if (entry is SpecializedEntry) {
|
||||
switch (entry) {
|
||||
case NewObjectTags():
|
||||
serializer.push(entry.cls);
|
||||
}
|
||||
} else {
|
||||
serializer.push(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,7 +753,16 @@ final class ObjectPoolSerializationCluster extends SerializationCluster {
|
||||
for (final pool in _objects) {
|
||||
serializer.writeUint(pool.entries.length);
|
||||
for (final entry in pool.entries) {
|
||||
serializer.writeRefId(entry);
|
||||
if (entry is SpecializedEntry) {
|
||||
switch (entry) {
|
||||
case NewObjectTags():
|
||||
serializer.writeUint(ObjectPoolEntryKind.newObjectTags.index);
|
||||
serializer.writeRefId(entry.cls);
|
||||
}
|
||||
} else {
|
||||
serializer.writeUint(ObjectPoolEntryKind.objectRef.index);
|
||||
serializer.writeRefId(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import 'dart:typed_data';
|
||||
import 'package:cfg/ir/constant_value.dart';
|
||||
import 'package:native_compiler/back_end/arm64/assembler.dart';
|
||||
import 'package:native_compiler/back_end/assembler.dart';
|
||||
import 'package:native_compiler/back_end/code.dart';
|
||||
import 'package:native_compiler/back_end/object_pool.dart';
|
||||
import 'package:native_compiler/runtime/vm_defs.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'disassembler.dart' show Disassembler;
|
||||
@@ -69,6 +71,47 @@ void main() {
|
||||
'str r1, [r0, #32760]\n',
|
||||
);
|
||||
});
|
||||
test('pairAddress', () {
|
||||
asm.ldp(R1, R2, asm.pairAddress(R0, -0x200));
|
||||
asm.stp(R1, R2, asm.pairAddress(R0, 0x1f8));
|
||||
// TODO: support large and unaligned offsets
|
||||
expectThrows(() {
|
||||
asm.pairAddress(R0, 3);
|
||||
});
|
||||
expectThrows(() {
|
||||
asm.pairAddress(R0, -1);
|
||||
});
|
||||
expectThrows(() {
|
||||
asm.pairAddress(R0, -0x208);
|
||||
});
|
||||
expectThrows(() {
|
||||
asm.pairAddress(R0, 0x200);
|
||||
});
|
||||
expectDisassembly(
|
||||
'ldp r1, r2, [r0, #-512]\n'
|
||||
'stp r1, r2, [r0, #504]\n',
|
||||
);
|
||||
});
|
||||
test('enterDartFrame', () {
|
||||
asm.enterDartFrame();
|
||||
expectDisassembly(
|
||||
'stp fp, lr, [sp, #-16]!\n'
|
||||
'mov fp, sp\n'
|
||||
'add pp, pp, #0x1\n'
|
||||
'stp pp, code, [sp, #-16]!\n'
|
||||
'ldr pp, [code, #${vmOffsets.Code_object_pool_offset - heapObjectTag}]\n'
|
||||
'sub pp, pp, #0x1\n',
|
||||
);
|
||||
});
|
||||
test('leaveDartFrame', () {
|
||||
asm.leaveDartFrame();
|
||||
expectDisassembly(
|
||||
'ldr pp, [fp, #-16]\n'
|
||||
'sub pp, pp, #0x1\n'
|
||||
'mov sp, fp\n'
|
||||
'ldp fp, lr, [sp], #16 !\n',
|
||||
);
|
||||
});
|
||||
test('push', () {
|
||||
asm.push(R0);
|
||||
asm.push(ZR);
|
||||
@@ -196,6 +239,55 @@ void main() {
|
||||
'mov r5, 0xff00ff00ff00ff00\n',
|
||||
);
|
||||
});
|
||||
test('addImmediate', () {
|
||||
asm.addImmediate(R0, R0, 0);
|
||||
asm.addImmediate(R1, R2, 0);
|
||||
asm.addImmediate(R1, R2, 0, .s32);
|
||||
asm.addImmediate(R1, R2, 0xabc);
|
||||
asm.addImmediate(R1, R2, -0xabc);
|
||||
asm.addImmediate(R1, R2, 0xabc000);
|
||||
asm.addImmediate(R1, R2, -0xabc000);
|
||||
asm.addImmediate(R1, R2, 0x11223344_55667788);
|
||||
asm.addImmediate(SP, FP, 0x11223344_55667788);
|
||||
expectDisassembly(
|
||||
'mov r1, r2\n'
|
||||
'movw r1, r2\n'
|
||||
'add r1, r2, #0xabc\n'
|
||||
'sub r1, r2, #0xabc\n'
|
||||
'add r1, r2, #0xabc000\n'
|
||||
'sub r1, r2, #0xabc000\n'
|
||||
'movz tmp, #0x7788\n'
|
||||
'movk tmp, #0x5566 lsl 16\n'
|
||||
'movk tmp, #0x3344 lsl 32\n'
|
||||
'movk tmp, #0x1122 lsl 48\n'
|
||||
'add r1, r2, tmp\n'
|
||||
'movz tmp, #0x7788\n'
|
||||
'movk tmp, #0x5566 lsl 16\n'
|
||||
'movk tmp, #0x3344 lsl 32\n'
|
||||
'movk tmp, #0x1122 lsl 48\n'
|
||||
'add csp, fp, tmp uxtx 0\n',
|
||||
);
|
||||
});
|
||||
test('andImmediate', () {
|
||||
asm.andImmediate(R1, R2, 0);
|
||||
asm.andImmediate(R1, R2, 0, .u32);
|
||||
asm.andImmediate(R1, R2, -1);
|
||||
asm.andImmediate(R1, R2, -1, .u32);
|
||||
asm.andImmediate(R1, R2, 0xff);
|
||||
asm.andImmediate(R1, R2, 0x11223344_55667788);
|
||||
expectDisassembly(
|
||||
'movz r1, #0x0\n'
|
||||
'movz r1, #0x0\n'
|
||||
'mov r1, r2\n'
|
||||
'movw r1, r2\n'
|
||||
'and r1, r2, 0xff\n'
|
||||
'movz tmp, #0x7788\n'
|
||||
'movk tmp, #0x5566 lsl 16\n'
|
||||
'movk tmp, #0x3344 lsl 32\n'
|
||||
'movk tmp, #0x1122 lsl 48\n'
|
||||
'and r1, r2, tmp\n',
|
||||
);
|
||||
});
|
||||
test('callRuntime', () {
|
||||
asm.callRuntime(RuntimeEntry.AllocateObject, 2);
|
||||
expectDisassembly(
|
||||
@@ -205,6 +297,15 @@ void main() {
|
||||
'blr lr\n',
|
||||
);
|
||||
});
|
||||
test('callStub', () {
|
||||
final stub = Code(null, Uint8List(0), ObjectPool());
|
||||
asm.callStub(stub);
|
||||
expectDisassembly(
|
||||
'ldr code, [pp, #${objectPoolBase}]\n'
|
||||
'ldr lr, [code, #${vmOffsets.Code_entry_point_offset.first - heapObjectTag}]\n'
|
||||
'blr lr\n',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('instruction', () {
|
||||
|
||||
@@ -1606,14 +1606,14 @@ class ARM64Decoder {
|
||||
void decodeAddSubShiftExt(Instr instr) {
|
||||
switch (instr.bit(30)) {
|
||||
case 0:
|
||||
if (instr.rdField() == R31) {
|
||||
if ((instr.rdField() == R31) && (instr.sField() == 1)) {
|
||||
format(instr, "cmn'sf 'rn, 'shift_op");
|
||||
} else {
|
||||
format(instr, "add'sf's 'rd, 'rn, 'shift_op");
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (instr.rdField() == R31) {
|
||||
if ((instr.rdField() == R31) && (instr.sField() == 1)) {
|
||||
format(instr, "cmp'sf 'rn, 'shift_op");
|
||||
} else {
|
||||
if (instr.rnField() == R31) {
|
||||
|
||||
@@ -16,7 +16,7 @@ B0 = EntryBlock() dominates:(B9, B11, B8)
|
||||
v1 = Parameter(a) # RA: R0 <- ()
|
||||
v2 = Parameter(b) # RA: R1 <- ()
|
||||
v7 = Comparison int & == 0(v1, v2) # RA: R0 <- (R0, R1)
|
||||
ParallelMove split(R0 -> stack[0])
|
||||
ParallelMove spill(R0 -> stack[0])
|
||||
Branch(v7, true: B8, false: B9) # RA: (R0)
|
||||
B8 = TargetBlock() idom:B0
|
||||
DirectCall print(v13) # RA: R0 <- (-) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
@@ -42,7 +42,7 @@ B0 = EntryBlock() dominates:(B11, B13, B10)
|
||||
v1 = Parameter(a) # RA: R0 <- ()
|
||||
v2 = Parameter(b) # RA: R1 <- ()
|
||||
v7 = Comparison int & == 0(v1, v2) # RA: R0 <- (R0, R1)
|
||||
ParallelMove split(R0 -> stack[0])
|
||||
ParallelMove spill(R0 -> stack[0])
|
||||
Branch(v7, true: B10, false: B11) # RA: (R0)
|
||||
B10 = TargetBlock() idom:B0
|
||||
DirectCall print(v15) # RA: R0 <- (-) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
@@ -63,7 +63,7 @@ B0 = EntryBlock() dominates:(B8, B14, B16, B7)
|
||||
v2 = Parameter(b) # RA: R1 <- ()
|
||||
v3 = Parameter(c) # RA: R2 <- ()
|
||||
v6 = Comparison int >(v1, v2) # RA: R0 <- (R0, R1)
|
||||
ParallelMove split(R0 -> stack[0])
|
||||
ParallelMove spill(R0 -> stack[0])
|
||||
Branch(v6, true: B7, false: B8) # RA: (R0)
|
||||
B7 = TargetBlock() idom:B0
|
||||
Goto(B16)
|
||||
@@ -149,15 +149,15 @@ B0 = EntryBlock()
|
||||
v21 = Constant(9)
|
||||
v36 = Constant(null)
|
||||
v1 = Parameter(x) # RA: R0 <- ()
|
||||
ParallelMove split(R0 -> stack[0])
|
||||
ParallelMove spill(R0 -> stack[0])
|
||||
v2 = TypeParameters() # RA: R1 <- ()
|
||||
ParallelMove split(R1 -> stack[1])
|
||||
ParallelMove spill(R1 -> stack[1])
|
||||
v5 = DirectCall _GrowableList.(v3, v4) # RA: R0 <- (-, -) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
DirectCall print(v5) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove split(stack[1] -> R1)
|
||||
v7 = TypeArguments(v2, <listLiterals.T%>) # RA: R0 <- (R1)
|
||||
ParallelMove split(R0 -> stack[2])
|
||||
ParallelMove spill(R0 -> stack[2])
|
||||
v8 = DirectCall _GrowableList.(v7, v4) # RA: R0 <- (R0, -) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
DirectCall print(v8) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
@@ -231,21 +231,21 @@ B0 = EntryBlock()
|
||||
v38 = Constant(2)
|
||||
v40 = Constant(3)
|
||||
v1 = Parameter(key) # RA: R0 <- ()
|
||||
ParallelMove split(R0 -> stack[0])
|
||||
ParallelMove spill(R0 -> stack[0])
|
||||
v2 = Parameter(value) # RA: R1 <- ()
|
||||
ParallelMove split(R1 -> stack[1])
|
||||
ParallelMove spill(R1 -> stack[1])
|
||||
v3 = Parameter(key2) # RA: R2 <- ()
|
||||
ParallelMove split(R2 -> stack[2])
|
||||
ParallelMove spill(R2 -> stack[2])
|
||||
v4 = Parameter(value2) # RA: R3 <- ()
|
||||
ParallelMove split(R3 -> stack[3])
|
||||
ParallelMove spill(R3 -> stack[3])
|
||||
v5 = TypeParameters() # RA: R4 <- ()
|
||||
ParallelMove split(R4 -> stack[4])
|
||||
ParallelMove spill(R4 -> stack[4])
|
||||
v30 = DirectCall Map._fromLiteral(v6, v29) # RA: R0 <- (-, -) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
DirectCall print(v30) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove split(stack[4] -> R1)
|
||||
v9 = TypeArguments(v5, <mapLiterals.S%, mapLiterals.T%>) # RA: R0 <- (R1)
|
||||
ParallelMove split(R0 -> stack[5])
|
||||
ParallelMove spill(R0 -> stack[5])
|
||||
v31 = DirectCall Map._fromLiteral(v9, v29) # RA: R0 <- (R0, -) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
DirectCall print(v31) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
@@ -299,11 +299,11 @@ B0 = EntryBlock()
|
||||
v28 = Constant(4)
|
||||
v30 = Constant(5)
|
||||
v1 = Parameter(x) # RA: R0 <- ()
|
||||
ParallelMove split(R0 -> stack[0])
|
||||
ParallelMove spill(R0 -> stack[0])
|
||||
v2 = Parameter(s) # RA: R1 <- ()
|
||||
ParallelMove split(R1 -> stack[1])
|
||||
ParallelMove spill(R1 -> stack[1])
|
||||
v3 = Parameter(o) # RA: R2 <- ()
|
||||
ParallelMove split(R2 -> stack[2])
|
||||
ParallelMove spill(R2 -> stack[2])
|
||||
v17 = DirectCall _StringBase._interpolateSingle(v3) # RA: R0 <- (R2) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
ParallelMove output(R0 -> vloc:R0)
|
||||
DirectCall print(v17) # RA: R0 <- (R0) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
|
||||
@@ -7,7 +7,7 @@ B0 = EntryBlock() dominates:(B5, B7, B4)
|
||||
v24 = Constant(4)
|
||||
v1 = Parameter(c1) # RA: R0 <- ()
|
||||
v2 = Parameter(c2) # RA: R1 <- ()
|
||||
ParallelMove split(R1 -> stack[0])
|
||||
ParallelMove spill(R1 -> stack[0])
|
||||
Branch(v1, true: B4, false: B5) # RA: (R0)
|
||||
B4 = TargetBlock() idom:B0
|
||||
DirectCall print(v9) # RA: R0 <- (-) temps: [R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R19, R20, R23, R25, V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30]
|
||||
@@ -64,7 +64,7 @@ B0 = EntryBlock() dominates:(B3)
|
||||
Goto(B3)
|
||||
B3 = JoinBlock(B0, B30) idom:B0 dominates:(B9, B8) loop-header (depth:1 body:(B3, B8, B12, B17, B30, B16, B24, B23) back-edges:(B30))
|
||||
v44 = Phi(v1, v39) # RA: R0 <- (-, R0)
|
||||
ParallelMove split(R0 -> stack[0])
|
||||
ParallelMove spill(R0 -> stack[0])
|
||||
CompareAndBranch int <(v44, v6, true: B8, false: B9) # RA: (R0, -)
|
||||
B8 = TargetBlock() idom:B3 dominates:(B12) in-loop:B3
|
||||
ParallelMove control(IntConstant(0) -> R1)
|
||||
@@ -86,7 +86,7 @@ B17 = TargetBlock() idom:B12 in-loop:B3
|
||||
B30 = JoinBlock(B17, B23) idom:B12 in-loop:B3
|
||||
ParallelMove split(stack[0] -> R0)
|
||||
v39 = BinaryIntOp +(v44, v33) # RA: R0 <- (R0, -)
|
||||
ParallelMove split(R0 -> stack[0])
|
||||
ParallelMove spill(R0 -> stack[0])
|
||||
Goto(B3)
|
||||
B9 = TargetBlock() idom:B3
|
||||
ParallelMove input(NullConstant(null) -> R0)
|
||||
|
||||
@@ -370,10 +370,6 @@ uword MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size) {
|
||||
dart::Object::ShouldHaveDeeplyImmutabilityBitSet(cid));
|
||||
}
|
||||
|
||||
word Object::tags_offset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const word UntaggedObject::kCardRememberedBit =
|
||||
dart::UntaggedObject::CardRememberedBit::shift();
|
||||
|
||||
@@ -557,10 +553,6 @@ bool Class::TraceAllocation(const dart::Class& klass) {
|
||||
return klass.TraceAllocation(dart::IsolateGroup::Current());
|
||||
}
|
||||
|
||||
word Instance::first_field_offset() {
|
||||
return TranslateOffsetInWords(dart::Instance::NextFieldOffset());
|
||||
}
|
||||
|
||||
word Instance::native_fields_array_offset() {
|
||||
return TranslateOffsetInWords(dart::Instance::NativeFieldsOffset());
|
||||
}
|
||||
|
||||
@@ -205,6 +205,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x14;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x1c;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x4;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -245,6 +246,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0xc;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0xd8;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -927,6 +929,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x28;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x34;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -968,6 +971,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0x18;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0x1b0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -1651,6 +1655,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x14;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x1c;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x4;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -1691,6 +1696,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0xc;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0xd8;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -2372,6 +2378,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x28;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x34;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -2413,6 +2420,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0x18;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0x1b0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -3099,6 +3107,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x28;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x34;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -3140,6 +3149,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0x18;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0x1b0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -3823,6 +3833,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x28;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x34;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -3864,6 +3875,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0x18;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0x1b0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -4548,6 +4560,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x14;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x1c;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x4;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -4588,6 +4601,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0xc;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0xd8;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -5271,6 +5285,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x28;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x34;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
@@ -5312,6 +5327,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0x18;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0x1b0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -5991,6 +6007,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x14;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x1c;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x4;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
|
||||
@@ -6029,6 +6046,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0xc;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0xd8;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -6705,6 +6723,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x28;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x34;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
|
||||
@@ -6744,6 +6763,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0x18;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0x1b0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -7421,6 +7441,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x14;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x1c;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x4;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
|
||||
@@ -7459,6 +7480,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0xc;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0xd8;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -8134,6 +8156,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x28;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x34;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
|
||||
@@ -8173,6 +8196,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0x18;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0x1b0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -8853,6 +8877,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x28;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x34;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
|
||||
@@ -8892,6 +8917,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0x18;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0x1b0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -9569,6 +9595,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x28;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x34;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
|
||||
@@ -9608,6 +9635,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0x18;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0x1b0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -10286,6 +10314,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x14;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x1c;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x4;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
|
||||
@@ -10324,6 +10353,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0xc;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0xd8;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -11001,6 +11031,7 @@ static constexpr dart::compiler::target::word ICData_NumArgsTestedShift = 0x0;
|
||||
static constexpr dart::compiler::target::word ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word ICData_owner_offset = 0x28;
|
||||
static constexpr dart::compiler::target::word ICData_state_bits_offset = 0x34;
|
||||
static constexpr dart::compiler::target::word Instance_first_field_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word IsolateGroup_object_store_offset =
|
||||
@@ -11040,6 +11071,7 @@ static constexpr dart::compiler::target::word NativeArguments_retval_offset =
|
||||
0x18;
|
||||
static constexpr dart::compiler::target::word NativeArguments_thread_offset =
|
||||
0x0;
|
||||
static constexpr dart::compiler::target::word Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_double_type_offset =
|
||||
0x1b0;
|
||||
static constexpr dart::compiler::target::word ObjectStore_int_type_offset =
|
||||
@@ -11743,6 +11775,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x10;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x14;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x4;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0xc;
|
||||
@@ -11786,6 +11820,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0xd8;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -12544,6 +12579,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x20;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0x18;
|
||||
@@ -12587,6 +12624,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0x1b0;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -13352,6 +13390,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x20;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0x18;
|
||||
@@ -13395,6 +13435,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0x1b0;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -14156,6 +14197,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x20;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0x18;
|
||||
@@ -14199,6 +14242,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0x1b0;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -14960,6 +15004,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x20;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0x18;
|
||||
@@ -15003,6 +15049,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0x1b0;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -15766,6 +15813,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x10;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x14;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x4;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0xc;
|
||||
@@ -15809,6 +15858,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0xd8;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -16568,6 +16618,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x20;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0x18;
|
||||
@@ -16611,6 +16663,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0x1b0;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -17366,6 +17419,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x10;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x14;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x4;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0xc;
|
||||
@@ -17407,6 +17462,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0xd8;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -18158,6 +18214,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x20;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0x18;
|
||||
@@ -18199,6 +18257,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0x1b0;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -18957,6 +19016,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x20;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0x18;
|
||||
@@ -18998,6 +19059,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0x1b0;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -19752,6 +19814,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x20;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0x18;
|
||||
@@ -19793,6 +19857,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0x1b0;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -20547,6 +20612,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x20;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0x18;
|
||||
@@ -20588,6 +20655,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0x1b0;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -21344,6 +21412,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x10;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x14;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x4;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0xc;
|
||||
@@ -21385,6 +21455,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0xc;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0xd8;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
@@ -22137,6 +22208,8 @@ static constexpr dart::compiler::target::word AOT_ICData_entries_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_owner_offset = 0x20;
|
||||
static constexpr dart::compiler::target::word AOT_ICData_state_bits_offset =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_Instance_first_field_offset =
|
||||
0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Int32x4_value_offset = 0x8;
|
||||
static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset =
|
||||
0x18;
|
||||
@@ -22178,6 +22251,7 @@ static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_retval_offset = 0x18;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_NativeArguments_thread_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word AOT_Object_tags_offset = 0x0;
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_ObjectStore_double_type_offset = 0x1b0;
|
||||
static constexpr dart::compiler::target::word AOT_ObjectStore_int_type_offset =
|
||||
|
||||
@@ -168,6 +168,7 @@
|
||||
FIELD(ICData, entries_offset) \
|
||||
FIELD(ICData, owner_offset) \
|
||||
FIELD(ICData, state_bits_offset) \
|
||||
FIELD(Instance, first_field_offset) \
|
||||
FIELD(Int32x4, value_offset) \
|
||||
FIELD(Isolate, finalizers_offset) \
|
||||
NOT_IN_PRODUCT(FIELD(Isolate, has_resumption_breakpoints_offset)) \
|
||||
@@ -191,6 +192,7 @@
|
||||
FIELD(NativeArguments, argv_offset) \
|
||||
FIELD(NativeArguments, retval_offset) \
|
||||
FIELD(NativeArguments, thread_offset) \
|
||||
FIELD(Object, tags_offset) \
|
||||
FIELD(ObjectStore, double_type_offset) \
|
||||
FIELD(ObjectStore, int_type_offset) \
|
||||
FIELD(ObjectStore, record_field_names_offset) \
|
||||
|
||||
@@ -82,6 +82,14 @@ class ModuleSnapshot : public AllStatic {
|
||||
kImplicitSetter,
|
||||
kFieldInitializer,
|
||||
};
|
||||
|
||||
// Object pool entry kinds in the module snapshots.
|
||||
// Should match ObjectPoolEntryKind enum
|
||||
// declared in pkg/native_compiler/lib/snapshot/snapshot.dart.
|
||||
enum ObjectPoolEntryKind {
|
||||
kObjectRef,
|
||||
kNewObjectTags,
|
||||
};
|
||||
};
|
||||
|
||||
class Deserializer;
|
||||
@@ -714,7 +722,11 @@ class CodeDeserializationCluster : public DeserializationCluster {
|
||||
}
|
||||
#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
|
||||
if (FLAG_disassemble_stubs) {
|
||||
Disassembler::DisassembleStub("", code);
|
||||
}
|
||||
#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
|
||||
}
|
||||
|
||||
#if !defined(PRODUCT)
|
||||
@@ -744,10 +756,14 @@ class ObjectPoolDeserializationCluster : public DeserializationCluster {
|
||||
void ReadFill(Deserializer* d_) override {
|
||||
Deserializer::Local d(d_);
|
||||
|
||||
const uint8_t entry_bits =
|
||||
const uint8_t tagged_entry_bits =
|
||||
ObjectPool::EncodeBits(ObjectPool::EntryType::kTaggedObject,
|
||||
ObjectPool::Patchability::kPatchable,
|
||||
ObjectPool::SnapshotBehavior::kSnapshotable);
|
||||
ObjectPool::Patchability::kNotPatchable,
|
||||
ObjectPool::SnapshotBehavior::kNotSnapshotable);
|
||||
const uint8_t immediate_entry_bits =
|
||||
ObjectPool::EncodeBits(ObjectPool::EntryType::kImmediate,
|
||||
ObjectPool::Patchability::kNotPatchable,
|
||||
ObjectPool::SnapshotBehavior::kNotSnapshotable);
|
||||
|
||||
for (intptr_t id = start_index_, n = stop_index_; id < n; id++) {
|
||||
const intptr_t length = d.ReadUnsigned();
|
||||
@@ -756,9 +772,26 @@ class ObjectPoolDeserializationCluster : public DeserializationCluster {
|
||||
ObjectPool::InstanceSize(length));
|
||||
pool->untag()->length_ = length;
|
||||
for (intptr_t j = 0; j < length; j++) {
|
||||
pool->untag()->entry_bits()[j] = entry_bits;
|
||||
UntaggedObjectPool::Entry& entry = pool->untag()->data()[j];
|
||||
entry.raw_obj_ = d.ReadRef();
|
||||
const auto kind =
|
||||
static_cast<ModuleSnapshot::ObjectPoolEntryKind>(d.ReadUnsigned());
|
||||
switch (kind) {
|
||||
case ModuleSnapshot::kObjectRef: {
|
||||
pool->untag()->entry_bits()[j] = tagged_entry_bits;
|
||||
UntaggedObjectPool::Entry& entry = pool->untag()->data()[j];
|
||||
entry.raw_obj_ = d.ReadRef();
|
||||
break;
|
||||
}
|
||||
case ModuleSnapshot::kNewObjectTags: {
|
||||
ClassPtr cls = static_cast<ClassPtr>(d.ReadRef());
|
||||
pool->untag()->entry_bits()[j] = immediate_entry_bits;
|
||||
UntaggedObjectPool::Entry& entry = pool->untag()->data()[j];
|
||||
entry.raw_value_ = compiler::target::MakeTagWordForNewSpaceObject(
|
||||
cls->untag()->id_,
|
||||
Object::RoundedAllocationSize(Class::host_instance_size(cls) *
|
||||
kCompressedWordSize));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -771,6 +804,9 @@ class ObjectPoolDeserializationCluster : public DeserializationCluster {
|
||||
pool ^= refs.At(id);
|
||||
|
||||
for (intptr_t i = 0, length = pool.Length(); i < length; ++i) {
|
||||
if (pool.TypeAt(i) != ObjectPool::EntryType::kTaggedObject) {
|
||||
continue;
|
||||
}
|
||||
obj = pool.ObjectAt(i);
|
||||
if (obj.IsAbstractType() || obj.IsTypeArguments()) {
|
||||
obj = Instance::Cast(obj).Canonicalize(d->thread());
|
||||
|
||||
@@ -1140,6 +1140,7 @@ class Object {
|
||||
friend class OneByteString;
|
||||
friend class TwoByteString;
|
||||
friend class Thread;
|
||||
friend class module_snapshot::ObjectPoolDeserializationCluster;
|
||||
|
||||
#define REUSABLE_FRIEND_DECLARATION(name) \
|
||||
friend class Reusable##name##HandleScope;
|
||||
@@ -8690,6 +8691,8 @@ class Instance : public Object {
|
||||
|
||||
static intptr_t NativeFieldsOffset() { return sizeof(UntaggedObject); }
|
||||
|
||||
static intptr_t first_field_offset() { return NextFieldOffset(); }
|
||||
|
||||
protected:
|
||||
#ifndef PRODUCT
|
||||
virtual void PrintSharedInstanceJSON(JSONObject* jsobj,
|
||||
|
||||
@@ -1325,6 +1325,7 @@ class UntaggedClass : public UntaggedObject {
|
||||
friend class CidRewriteVisitor;
|
||||
friend class FinalizeVMIsolateVisitor;
|
||||
friend class Api;
|
||||
friend class module_snapshot::ObjectPoolDeserializationCluster;
|
||||
};
|
||||
|
||||
class UntaggedPatchClass : public UntaggedObject {
|
||||
|
||||
Reference in New Issue
Block a user