blob: d19ce6a9b20bb46142d53c7c2102742b49b56df0 [file]
// 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/code.dart';
import 'package:native_compiler/back_end/locations.dart';
/// Interface class for architecture-specific stub code generator.
abstract interface class StubCodeGenerator {
Code generate(String name);
}
/// 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 = {};
Map<(Register, Register, bool), Code> _writeBarrierStubs = {};
List<Code?> _subtypeTestCacheStubs = List<Code?>.filled(8, null);
late final Code dynamicCallStub = _generateCode(
'DynamicCallStub',
dynamicCallStubGenerator(),
);
late final Code dynamicInvocationForwarderStub = _generateCode(
'DynamicInvocationForwarderStub',
dynamicInvocationForwarderStubGenerator(),
);
StubFactory(this.consumeGeneratedCode);
StubCodeGenerator allocationStubGenerator(ast.Class cls);
StubCodeGenerator writeBarrierStubGenerator(
Register objectReg,
Register valueReg,
bool isArray,
);
StubCodeGenerator dynamicCallStubGenerator();
StubCodeGenerator dynamicInvocationForwarderStubGenerator();
StubCodeGenerator subtypeTestCacheStubGenerator(int n);
Code _generateCode(String name, StubCodeGenerator generator) {
final code = generator.generate(name);
consumeGeneratedCode(code);
return code;
}
Code getAllocationStub(ast.Class cls) => _allocationStubs[cls] ??=
_generateCode('AllocationStub for ${cls}', allocationStubGenerator(cls));
Code getWriteBarrierStub(
Register objectReg,
Register valueReg,
bool isArray,
) => _writeBarrierStubs[(objectReg, valueReg, isArray)] ??= _generateCode(
'WriteBarrierStub for $objectReg, $valueReg${isArray ? ' array' : ''}',
writeBarrierStubGenerator(objectReg, valueReg, isArray),
);
Code getSubtypeTestCacheStub(int numInputs) =>
_subtypeTestCacheStubs[numInputs] ??= _generateCode(
'SubtypeTestCacheStub',
subtypeTestCacheStubGenerator(numInputs),
);
}