diff --git a/pkg/cfg/lib/front_end/ast_to_ir.dart b/pkg/cfg/lib/front_end/ast_to_ir.dart index 959d3dee19f..7f86c7c1630 100644 --- a/pkg/cfg/lib/front_end/ast_to_ir.dart +++ b/pkg/cfg/lib/front_end/ast_to_ir.dart @@ -208,7 +208,7 @@ class AstToIr extends ast.RecursiveVisitor { if (!field.isStatic) { if (field.isLate) { if (!initializedFields.contains(field)) { - throw 'Unimplemented: _initLateInstanceField'; + throw 'Unimplemented: initialization of late instance field'; } } else { final fieldInitializer = field.initializer; @@ -499,7 +499,7 @@ class AstToIr extends ast.RecursiveVisitor { if (!enableAsserts) { return; } - throw 'unimplemented'; + throw 'Unsupported node ${node.runtimeType} with enabled asserts'; } @override @@ -742,7 +742,9 @@ class AstToIr extends ast.RecursiveVisitor { @override void visitVariableDeclaration(ast.VariableDeclaration node) { - if (node.isLate) throw 'unimplemented'; + if (node.isLate) { + throw 'Unsupported node ${node.runtimeType} for late variable'; + } if (node.isConst) return; final local = localVarIndexer.variableForDeclaration(node); final initializer = node.initializer; @@ -762,7 +764,9 @@ class AstToIr extends ast.RecursiveVisitor { @override void visitVariableGet(ast.VariableGet node) { final variable = node.variable; - if (variable.isLate) throw 'unimplemented'; + if (variable.isLate) { + throw 'Unsupported node ${node.runtimeType} for late variable'; + } if (variable.isConst) { builder.addConstant( ConstantValue( @@ -789,7 +793,9 @@ class AstToIr extends ast.RecursiveVisitor { @override void visitVariableSet(ast.VariableSet node) { final variable = node.variable; - if (variable.isLate) throw 'unimplemented'; + if (variable.isLate) { + throw 'Unsupported node ${node.runtimeType} for late variable'; + } _translateNode(node.value); if (_handleUnreachableExpression(1)) return; final local = localVarIndexer.variableForDeclaration(variable); diff --git a/pkg/cfg/lib/ir/functions.dart b/pkg/cfg/lib/ir/functions.dart index 2d782b88144..2d17b42baa4 100644 --- a/pkg/cfg/lib/ir/functions.dart +++ b/pkg/cfg/lib/ir/functions.dart @@ -2,6 +2,7 @@ // 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:cfg/ir/source_position.dart'; import 'package:cfg/ir/types.dart'; import 'package:cfg/utils/misc.dart'; @@ -22,6 +23,8 @@ sealed class CFunction { CFunction._(this.member); + ast.FunctionNode? get functionNode => member.function; + /// Whether this function has a receiver parameter. bool get hasReceiverParameter => member.isInstanceMember || member is ast.Constructor; @@ -36,12 +39,62 @@ sealed class CFunction { /// Whether this function has function type parameters. bool get hasFunctionTypeParameters => - member is ast.Procedure && member.function!.typeParameters.isNotEmpty; + functionNode?.typeParameters.isNotEmpty ?? false; - /// Total number of parameters including function type parameters - /// (represented with a single parameter), receiver, closure and + /// Number of implicit parameters of this function: + /// - function type parameters (represented with a single parameter), + /// - receiver, + /// - closure. + int get numberOfImplicitParameters => + (hasFunctionTypeParameters ? 1 : 0) + + (hasReceiverParameter ? 1 : 0) + + (hasClosureParameter ? 1 : 0); + + /// Number of required positional parameters including implicit parameters. + int get numberOfRequiredPositionalParameters => + numberOfImplicitParameters + (functionNode?.requiredParameterCount ?? 0); + + /// Total number of parameters including implicit parameters and /// optional parameters. - int get numberOfParameters; + int get numberOfParameters => + numberOfImplicitParameters + + (functionNode?.positionalParameters.length ?? 0) + + (functionNode?.namedParameters.length ?? 0); + + /// Whether this function has optional positional parameters. + bool get hasOptionalPositionalParameters => + functionNode != null && + (functionNode!.requiredParameterCount < + functionNode!.positionalParameters.length); + + /// Whether this function has named parameters. + bool get hasNamedParameters => + functionNode?.namedParameters.isNotEmpty ?? false; + + ast.VariableDeclaration _getOptionalOrNamedParameter(int index) => + hasOptionalPositionalParameters + ? functionNode!.positionalParameters[index - numberOfImplicitParameters] + : functionNode!.namedParameters[index - + numberOfRequiredPositionalParameters]; + + /// Default value of the [index]-th optional or named parameter. + ConstantValue getParameterDefaultValue(int index) => ConstantValue( + (_getOptionalOrNamedParameter(index).initializer as ast.ConstantExpression) + .constant, + ); + + /// Name of the [index]-th named parameter. + /// Named parameters are sorted by name and follow required positional parameters. + String getParameterName(int index) { + assert(hasNamedParameters); + return _getOptionalOrNamedParameter(index).name!; + } + + /// Whether the [index]-th named parameter is required. + bool isRequiredParameter(int index) { + assert(hasNamedParameters); + return _getOptionalOrNamedParameter(index).isRequired; + } /// Return type of this function. CType get returnType; @@ -55,7 +108,13 @@ final class GetterFunction extends CFunction { GetterFunction._(super.member) : assert(member.hasGetter), super._(); @override - int get numberOfParameters => member.isInstanceMember ? 1 /* receiver */ : 0; + ast.FunctionNode? get functionNode => null; + + @override + int get numberOfRequiredPositionalParameters => numberOfImplicitParameters; + + @override + int get numberOfParameters => numberOfImplicitParameters; @override late final CType returnType = CType.fromStaticType(member.getterType); @@ -74,8 +133,14 @@ final class SetterFunction extends CFunction { SetterFunction._(super.member) : assert(member.hasSetter), super._(); @override - int get numberOfParameters => - member.isInstanceMember ? 2 /* receiver, value */ : 1 /* only value */; + ast.FunctionNode? get functionNode => null; + + @override + int get numberOfRequiredPositionalParameters => + numberOfImplicitParameters + 1 /* value */; + + @override + int get numberOfParameters => numberOfImplicitParameters + 1 /* value */; @override CType get returnType => const TopType(const ast.VoidType()); @@ -99,7 +164,13 @@ final class FieldInitializerFunction extends CFunction { super._(); @override - int get numberOfParameters => member.isInstanceMember ? 1 /* receiver */ : 0; + ast.FunctionNode? get functionNode => null; + + @override + int get numberOfRequiredPositionalParameters => numberOfImplicitParameters; + + @override + int get numberOfParameters => numberOfImplicitParameters; @override CType get returnType => CType.fromStaticType(member.getterType); @@ -116,16 +187,7 @@ final class RegularFunction extends CFunction { super._(); @override - int get numberOfParameters => - (hasFunctionTypeParameters ? 1 : 0) + - (hasReceiverParameter ? 1 : 0) + - member.function!.positionalParameters.length + - member.function!.namedParameters.length; - - @override - late final CType returnType = CType.fromStaticType( - member.function!.returnType, - ); + late final CType returnType = CType.fromStaticType(functionNode!.returnType); @override String toString() => member.toString(); @@ -135,12 +197,6 @@ final class RegularFunction extends CFunction { final class GenerativeConstructor extends CFunction { GenerativeConstructor._(ast.Constructor super.member) : super._(); - @override - int get numberOfParameters => - 1 /* receiver */ + - member.function!.positionalParameters.length + - member.function!.namedParameters.length; - @override CType get returnType => const TopType(const ast.VoidType()); @@ -164,24 +220,14 @@ final class LocalFunction extends ClosureFunction { final ast.LocalFunction localFunction; LocalFunction._(super.member, this.localFunction) : super._(); + @override + ast.FunctionNode? get functionNode => localFunction.function; + @override String toString() => 'closure $localFunction at $member'; @override - bool get hasFunctionTypeParameters => - localFunction.function.typeParameters.isNotEmpty; - - @override - int get numberOfParameters => - (hasFunctionTypeParameters ? 1 : 0) + - 1 /* closure */ + - localFunction.function.positionalParameters.length + - localFunction.function.namedParameters.length; - - @override - late final CType returnType = CType.fromStaticType( - localFunction.function.returnType, - ); + late final CType returnType = CType.fromStaticType(functionNode!.returnType); @override SourcePosition get sourcePosition => SourcePosition(localFunction.fileOffset); @@ -202,13 +248,6 @@ final class TearOffFunction extends ClosureFunction { ? member.enclosingClass!.typeParameters.isNotEmpty : member.function!.typeParameters.isNotEmpty; - @override - int get numberOfParameters => - (hasFunctionTypeParameters ? 1 : 0) + - 1 /* closure */ + - member.function!.positionalParameters.length + - member.function!.namedParameters.length; - @override late final CType returnType = CType.fromStaticType( member is ast.Constructor diff --git a/pkg/native_compiler/lib/back_end/arm64/assembler.dart b/pkg/native_compiler/lib/back_end/arm64/assembler.dart index f98ac0c2a79..c604ff3e3b2 100644 --- a/pkg/native_compiler/lib/back_end/arm64/assembler.dart +++ b/pkg/native_compiler/lib/back_end/arm64/assembler.dart @@ -125,6 +125,18 @@ final allocatableRegisters = allRegisters .where((r) => !reservedRegisters.contains(r)) .toList(); +final argumentRegisters = allocatableRegisters + .where((r) => r != argumentsDescriptorReg) + .take(16) + .toList(); + +final prologueScratchRegisters = allocatableRegisters + .where( + (r) => + r != argumentsDescriptorReg && r.index > argumentRegisters.last.index, + ) + .toList(); + /// Floating-point registers. const FPRegister V0 = FPRegister(0, 'V0'); const FPRegister V1 = FPRegister(1, 'V1'); diff --git a/pkg/native_compiler/lib/back_end/arm64/code_generator.dart b/pkg/native_compiler/lib/back_end/arm64/code_generator.dart index b4e79abbc78..a4e56978335 100644 --- a/pkg/native_compiler/lib/back_end/arm64/code_generator.dart +++ b/pkg/native_compiler/lib/back_end/arm64/code_generator.dart @@ -2,6 +2,8 @@ // 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:math' as math; + import 'package:cfg/ir/constant_value.dart'; import 'package:cfg/ir/field.dart'; import 'package:cfg/ir/functions.dart'; @@ -11,6 +13,7 @@ import 'package:cfg/ir/types.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/stack_frame.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'; @@ -36,6 +39,234 @@ final class Arm64CodeGenerator extends CodeGenerator { stackPointerReg, stackFrame.frameSizeToAllocate, ); + final function = graph.function; + if (function.hasOptionalPositionalParameters) { + _prepareOptionalPositionalParameters(function); + } else if (function.hasNamedParameters) { + _prepareNamedParameters(function); + } + } + + /// Load positional required and optional arguments into argument registers, + /// filling in the default values if optional arguments are not passed. + /// Extra arguments are copied to the shadow parameters area on the stack. + void _prepareOptionalPositionalParameters(CFunction function) { + final argCountReg = prologueScratchRegisters[0]; + final argPtrReg = prologueScratchRegisters[1]; + + final numRequired = function.numberOfRequiredPositionalParameters; + final total = function.numberOfParameters; + assert(numRequired < total); + + // TODO: compressed pointers + // Load total number of arguments as a Smi. + _asm.ldr( + argCountReg, + _asm.fieldAddress( + argumentsDescriptorReg, + vmOffsets.ArgumentsDescriptor_count_offset, + ), + ); + // Arguments pointer points to the first pair of arguments. + assert(Arm64StackFrame.lastParameterOffsetFromFP == 2 * wordSize); + _asm.add( + argPtrReg, + FP, + ShiftedRegOperand(argCountReg, .LSL, log2wordSize - smiShift), + ); + // Label for each number of optional arguments passed. + final labels = List.generate(total - numRequired, (_) => Label()); + + var i = 0; + final int numArgsToLoadInPairs = math.min(total, argumentRegisters.length); + for (; i + 1 < numArgsToLoadInPairs; i += 2) { + if (i >= numRequired) { + _asm.cmp(argCountReg, Immediate((i + 1) << smiShift)); + _asm.b(labels[i - numRequired], .less); + } + // TODO: pass arguments on registers and avoid these loads + _asm.ldp( + argumentRegisters[i + 1], + argumentRegisters[i], + _asm.pairAddress(argPtrReg, -i * wordSize), + ); + if (i >= numRequired) { + _asm.b(labels[i + 1 - numRequired], .equal); + } else if (i + 1 >= numRequired) { + _asm.cmp(argCountReg, Immediate((i + 1) << smiShift)); + _asm.b(labels[i + 1 - numRequired], .equal); + } + } + for (; i < total; ++i) { + if (i >= numRequired) { + _asm.cmp(argCountReg, Immediate(i << smiShift)); + _asm.b(labels[i - numRequired], .equal); + } + final reg = (i < argumentRegisters.length) + ? argumentRegisters[i] + : tempReg; + _asm.ldr(reg, _asm.address(argPtrReg, -(i - 1) * wordSize)); + if (i >= argumentRegisters.length) { + _asm.str( + reg, + _asm.address(FP, stackFrame.shadowParameterOffsetFromFP(i)), + ); + } + } + final done = Label(); + _asm.b(done); + for (var i = numRequired; i < total; ++i) { + _asm.bind(labels[i - numRequired]); + final reg = (i < argumentRegisters.length) + ? argumentRegisters[i] + : tempReg; + _asm.loadConstant(reg, function.getParameterDefaultValue(i)); + if (i >= argumentRegisters.length) { + _asm.str( + reg, + _asm.address(FP, stackFrame.shadowParameterOffsetFromFP(i)), + ); + } + } + _asm.bind(done); + } + + /// Load required positional and named arguments into argument registers, + /// filling in the default values if optional arguments are not passed. + /// Extra arguments are copied to the shadow parameters area on the stack. + void _prepareNamedParameters(CFunction function) { + final argPtrReg = prologueScratchRegisters[0]; + final argNameReg = prologueScratchRegisters[1]; + + final numRequired = function.numberOfRequiredPositionalParameters; + final total = function.numberOfParameters; + assert(numRequired < total); + + // TODO: compressed pointers + // Load total number of arguments as a Smi. + _asm.ldr( + tempReg, + _asm.fieldAddress( + argumentsDescriptorReg, + vmOffsets.ArgumentsDescriptor_count_offset, + ), + ); + // Arguments pointer points to the first pair of arguments. + assert(Arm64StackFrame.lastParameterOffsetFromFP == 2 * wordSize); + _asm.add( + argPtrReg, + FP, + ShiftedRegOperand(tempReg, .LSL, log2wordSize - smiShift), + ); + + var i = 0; + final int numArgsToLoadInPairs = math.min( + numRequired, + argumentRegisters.length, + ); + for (; i + 1 < numArgsToLoadInPairs; i += 2) { + // TODO: pass arguments on registers and avoid these loads + _asm.ldp( + argumentRegisters[i + 1], + argumentRegisters[i], + _asm.pairAddress(argPtrReg, -i * wordSize), + ); + } + for (; i < numRequired; ++i) { + final reg = (i < argumentRegisters.length) + ? argumentRegisters[i] + : tempReg; + _asm.ldr(reg, _asm.address(argPtrReg, -(i - 1) * wordSize)); + if (i >= argumentRegisters.length) { + _asm.str( + reg, + _asm.address(FP, stackFrame.shadowParameterOffsetFromFP(i)), + ); + } + } + + // Each argument entry has 2 words: name and position. + assert(vmOffsets.ArgumentsDescriptor_name_offset == 0); + assert(vmOffsets.ArgumentsDescriptor_position_offset == wordSize); + assert(vmOffsets.ArgumentsDescriptor_named_entry_size == 2 * wordSize); + + // argumentsDescriptorReg points to the position field of the current argument. + _asm.add( + argumentsDescriptorReg, + argumentsDescriptorReg, + Immediate( + vmOffsets.ArgumentsDescriptor_first_named_entry_offset + + vmOffsets.ArgumentsDescriptor_position_offset, + ), + ); + + if (!function.isRequiredParameter(numRequired)) { + // Load name of the first optional named parameter. + _asm.ldr( + argNameReg, + RegOffsetAddress( + argumentsDescriptorReg, + -vmOffsets.ArgumentsDescriptor_position_offset + + vmOffsets.ArgumentsDescriptor_name_offset, + ), + ); + } + + for (i = numRequired; i < total; ++i) { + Label? proceed; + final destReg = (i < argumentRegisters.length) + ? argumentRegisters[i] + : tempReg; + if (!function.isRequiredParameter(i)) { + _asm.loadFromPool(tempReg, function.getParameterName(i)); + _asm.cmp(argNameReg, tempReg); + final passed = Label(); + _asm.b(passed, .equal); + + _asm.loadConstant(destReg, function.getParameterDefaultValue(i)); + proceed = Label(); + _asm.b(proceed); + + _asm.bind(passed); + } + if (i + 1 < total && !function.isRequiredParameter(i + 1)) { + // Load both position of this argument and the name of the next argument. + _asm.ldp( + tempReg, + argNameReg, + WritebackRegOffsetAddress( + argumentsDescriptorReg, + vmOffsets.ArgumentsDescriptor_named_entry_size, + isPostIndexed: true, + ), + ); + } else { + // Only load the position of this argument. + _asm.ldr( + tempReg, + WritebackRegOffsetAddress( + argumentsDescriptorReg, + vmOffsets.ArgumentsDescriptor_named_entry_size, + isPostIndexed: true, + ), + ); + } + _asm.sub( + tempReg, + argPtrReg, + ShiftedRegOperand(tempReg, .LSL, log2wordSize - smiShift), + ); + _asm.ldr(destReg, RegOffsetAddress(tempReg, wordSize)); + if (proceed != null) { + _asm.bind(proceed); + } + if (i >= argumentRegisters.length) { + _asm.str( + destReg, + _asm.address(FP, stackFrame.shadowParameterOffsetFromFP(i)), + ); + } + } } void _generateBranch( diff --git a/pkg/native_compiler/lib/back_end/arm64/constraints.dart b/pkg/native_compiler/lib/back_end/arm64/constraints.dart index db867c356cf..50f4c47e257 100644 --- a/pkg/native_compiler/lib/back_end/arm64/constraints.dart +++ b/pkg/native_compiler/lib/back_end/arm64/constraints.dart @@ -65,16 +65,35 @@ final class Arm64Constraints extends Constraints { // TODO: pass arguments on registers Constraint parameterConstraint(Parameter instr) { final paramIndex = instr.variable.index; - final numParams = instr.graph.function.numberOfParameters; + final function = instr.graph.function; + final numParams = function.numberOfParameters; assert(0 <= paramIndex && paramIndex < numParams); + Constraint? paramConstraint = _parameters?[paramIndex]; + if (paramConstraint != null) { + return paramConstraint; + } + if (function.hasOptionalPositionalParameters || + function.hasNamedParameters) { + if (paramIndex < argumentRegisters.length) { + paramConstraint = argumentRegisters[paramIndex]; + } else { + paramConstraint = ParameterStackLocation( + paramIndex - argumentRegisters.length, + registerClass(instr), + ); + } + } else { + paramConstraint = ParameterStackLocation( + paramIndex, + registerClass(instr), + ); + } final parameters = (_parameters ??= List.filled( numParams, null, )); - return parameters[paramIndex] ??= ParameterStackLocation( - paramIndex, - registerClass(instr), - ); + parameters[paramIndex] = paramConstraint; + return paramConstraint; } @override diff --git a/pkg/native_compiler/lib/back_end/arm64/stack_frame.dart b/pkg/native_compiler/lib/back_end/arm64/stack_frame.dart index e55a27fb390..74c687f06eb 100644 --- a/pkg/native_compiler/lib/back_end/arm64/stack_frame.dart +++ b/pkg/native_compiler/lib/back_end/arm64/stack_frame.dart @@ -19,6 +19,7 @@ import 'package:native_compiler/back_end/stack_frame.dart'; /// FP -> [saved FP] /// [Code] /// [saved tagged ObjectPool] +/// [shadow space for optional parameters] /// [spill slot 0] /// ... /// [spill slot M] @@ -36,12 +37,23 @@ final class Arm64StackFrame extends StackFrame { /// Offset of the saved pool pointer relative to FP. static const int poolPointerOffsetFromFP = -2 * wordSize; - /// Offset of the first spill slot, relative to FP - static const int firstSpillSlotOffsetFromFP = -3 * wordSize; + /// Offset of the first shadow parameter, relative to FP + static const int shadowParametersOffsetFromFP = -3 * wordSize; /// Stack frame alignment. static const int alignment = 2 * wordSize; + /// Number of stack slots reserved for shadow parameters. + late final int _shadowParametersStackSlots = + ((function.hasOptionalPositionalParameters || + function.hasNamedParameters) && + function.numberOfParameters > argumentRegisters.length) + ? function.numberOfParameters - argumentRegisters.length + : 0; + + late final int _firstSpillSlotOffsetFromFP = + shadowParametersOffsetFromFP - _shadowParametersStackSlots * wordSize; + Arm64StackFrame(super.function); @override @@ -61,17 +73,36 @@ final class Arm64StackFrame extends StackFrame { assert(isFinalized); switch (location) { case SpillSlot(): - return firstSpillSlotOffsetFromFP - location.index * wordSize; + return _firstSpillSlotOffsetFromFP - location.index * wordSize; case ParameterStackLocation(): final paramIndex = location.paramIndex; final numParams = function.numberOfParameters; assert(0 <= paramIndex && paramIndex < numParams); - return lastParameterOffsetFromFP + - (numParams - paramIndex - 1) * wordSize; + if (function.hasOptionalPositionalParameters || + function.hasNamedParameters) { + return shadowParameterOffsetFromFP(paramIndex); + } else { + return lastParameterOffsetFromFP + + (numParams - paramIndex - 1) * wordSize; + } } } @override - int get frameSizeToAllocate => - roundUp((usedSpillSlots + maxArgumentsStackSlots) * wordSize, alignment); + int shadowParameterOffsetFromFP(int paramIndex) { + assert( + function.hasOptionalPositionalParameters || function.hasNamedParameters, + ); + assert(paramIndex >= argumentRegisters.length); + assert(paramIndex < function.numberOfParameters); + return shadowParametersOffsetFromFP - + (paramIndex - argumentRegisters.length) * wordSize; + } + + @override + int get frameSizeToAllocate => roundUp( + (_shadowParametersStackSlots + usedSpillSlots + maxArgumentsStackSlots) * + wordSize, + alignment, + ); } diff --git a/pkg/native_compiler/lib/back_end/register_allocator.dart b/pkg/native_compiler/lib/back_end/register_allocator.dart index 31a39d14ee7..0acc8b89592 100644 --- a/pkg/native_compiler/lib/back_end/register_allocator.dart +++ b/pkg/native_compiler/lib/back_end/register_allocator.dart @@ -146,8 +146,8 @@ final class LinearScanRegisterAllocator extends RegisterAllocator { _instructionByPos[pos ~/ step] = block.id; pos += step; for (final instr in block) { - if (instr is Phi) { - // All Phis have the same position as their Block. + if (instr is Phi || instr is Parameter) { + // All Phis and Parameters have the same position as their Block. _instructionPos[instr.id] = blockStartPos(block); } else { _instructionPos[instr.id] = pos; diff --git a/pkg/native_compiler/lib/back_end/stack_frame.dart b/pkg/native_compiler/lib/back_end/stack_frame.dart index b8afc123f6a..adf7f045e1f 100644 --- a/pkg/native_compiler/lib/back_end/stack_frame.dart +++ b/pkg/native_compiler/lib/back_end/stack_frame.dart @@ -42,6 +42,10 @@ abstract base class StackFrame { /// Should be used only after the frame is finalized. int offsetFromFP(StackLocation location); + /// Offset of the shadow parameter relative to the frame pointer, in bytes. + /// Should be used only after the frame is finalized. + int shadowParameterOffsetFromFP(int paramIndex); + /// Frame size to allocate, in bytes. /// Should be used only after the frame is finalized. int get frameSizeToAllocate; diff --git a/pkg/native_compiler/lib/runtime/vm_defs.dart b/pkg/native_compiler/lib/runtime/vm_defs.dart index 79195c1c06f..ca34a7d8926 100644 --- a/pkg/native_compiler/lib/runtime/vm_defs.dart +++ b/pkg/native_compiler/lib/runtime/vm_defs.dart @@ -7,6 +7,7 @@ export 'vm_offsets.g.dart'; const int smiBit = 0; const int heapObjectTag = 1; +const int smiShift = 1; const int barrierOverlapShift = 2; int objectAlignment(int wordSize) => wordSize * 2; diff --git a/pkg/native_compiler/testcases/lowering_test.dart.expect b/pkg/native_compiler/testcases/lowering_test.dart.expect index c2498d67ca2..f4ae11a7fbf 100644 --- a/pkg/native_compiler/testcases/lowering_test.dart.expect +++ b/pkg/native_compiler/testcases/lowering_test.dart.expect @@ -191,9 +191,9 @@ B0 = EntryBlock() v23 = Constant(8) v24 = Constant(9) v1 = Parameter(#functionTypeParameters) # RA: param[0] <- () - ParallelMove output(param[0] -> vloc:R0) + ParallelMove output(param[0] -> vloc:R1) v2 = Parameter(x) # RA: param[1] <- () - ParallelMove output(param[1] -> vloc:R1) + ParallelMove output(param[1] -> vloc:R0) v7 = DirectCall _GrowableList.(v5, v6) # 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(v7) # 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]