mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 08:44:27 +00:00
b85679eaf3
Right now all type literal usages will perform a runtime call which is rather slow. Flutter happens to use type literals such as `return T;` in hot code which causes this to show up in the profile. This CL adds fast paths for type parameter type literals if the type parameter value (i.e. entry of TAV corresponding to T): * is `null`: return `dynamic` * is a non-FutureOr [Type] with compatible nullability: return value * is [FunctionType] with compatible nullability: return value otherwise fall back to runtime call. It makes simple type literal uses 10x+ faster - the kinds that Flutter is using. Issue https://github.com/dart-lang/sdk/issues/48757 TEST=vm/dart{,_2}/instantiate_type_literal_test Change-Id: I1139d6689aedbc68321f47ee6c9946a3323fbf6e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/241968 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
85 lines
2.7 KiB
C++
85 lines
2.7 KiB
C++
// Copyright (c) 2018, 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.
|
|
|
|
#ifndef RUNTIME_VM_CONSTANTS_H_
|
|
#define RUNTIME_VM_CONSTANTS_H_
|
|
|
|
#if defined(TARGET_ARCH_IA32)
|
|
#include "vm/constants_ia32.h"
|
|
#elif defined(TARGET_ARCH_X64)
|
|
#include "vm/constants_x64.h"
|
|
#elif defined(TARGET_ARCH_ARM)
|
|
#include "vm/constants_arm.h"
|
|
#elif defined(TARGET_ARCH_ARM64)
|
|
#include "vm/constants_arm64.h"
|
|
#elif defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
|
|
#include "vm/constants_riscv.h"
|
|
#else
|
|
#error Unknown architecture.
|
|
#endif
|
|
|
|
namespace dart {
|
|
|
|
// An architecture independent ABI for the InstantiateType stub.
|
|
//
|
|
// We re-use registers from another ABI to avoid duplicating this ABI across 4
|
|
// architectures.
|
|
struct InstantiateTypeABI {
|
|
static constexpr Register kTypeReg =
|
|
InstantiationABI::kUninstantiatedTypeArgumentsReg;
|
|
static constexpr Register kInstantiatorTypeArgumentsReg =
|
|
InstantiationABI::kInstantiatorTypeArgumentsReg;
|
|
static constexpr Register kFunctionTypeArgumentsReg =
|
|
InstantiationABI::kFunctionTypeArgumentsReg;
|
|
static constexpr Register kResultTypeReg = InstantiationABI::kResultTypeReg;
|
|
static constexpr Register kScratchReg = InstantiationABI::kScratchReg;
|
|
};
|
|
|
|
class RegisterNames {
|
|
public:
|
|
static const char* RegisterName(Register reg) {
|
|
ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters));
|
|
return cpu_reg_names[reg];
|
|
}
|
|
static const char* RegisterAbiName(Register reg) {
|
|
ASSERT((0 <= reg) && (reg < kNumberOfCpuRegisters));
|
|
return cpu_reg_abi_names[reg];
|
|
}
|
|
static const char* FpuRegisterName(FpuRegister reg) {
|
|
ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
|
|
return fpu_reg_names[reg];
|
|
}
|
|
#if defined(TARGET_ARCH_ARM)
|
|
static const char* FpuSRegisterName(SRegister reg) {
|
|
ASSERT((0 <= reg) && (reg < kNumberOfSRegisters));
|
|
return fpu_s_reg_names[reg];
|
|
}
|
|
static const char* FpuDRegisterName(DRegister reg) {
|
|
ASSERT((0 <= reg) && (reg < kNumberOfDRegisters));
|
|
return fpu_d_reg_names[reg];
|
|
}
|
|
#endif // defined(TARGET_ARCH_ARM)
|
|
};
|
|
|
|
static constexpr bool IsArgumentRegister(Register reg) {
|
|
return ((1 << reg) & CallingConventions::kArgumentRegisters) != 0;
|
|
}
|
|
|
|
static constexpr bool IsFpuArgumentRegister(FpuRegister reg) {
|
|
return ((1 << reg) & CallingConventions::kFpuArgumentRegisters) != 0;
|
|
}
|
|
|
|
static constexpr bool IsCalleeSavedRegister(Register reg) {
|
|
return ((1 << reg) & CallingConventions::kCalleeSaveCpuRegisters) != 0;
|
|
}
|
|
|
|
#if !defined(TARGET_ARCH_IA32)
|
|
constexpr bool IsAbiPreservedRegister(Register reg) {
|
|
return (kAbiPreservedCpuRegs & (1 << reg)) != 0;
|
|
}
|
|
#endif
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_CONSTANTS_H_
|