Register alloc config for kRootRegister on ia32
This CL prepares the way for adding a root register on ia32. The new register allocation configuration PreserveRootIA32 treats kRootRegister as an unallocatable register. Note that kRootRegister (on ia32) is still completely unused, unallocated, and may be clobbered at many points. This is left to future work. Bug: v8:6666 Change-Id: I4aacdf9c3bb365d6ed49fea8f013f79b7b1f0a98 Reviewed-on: https://chromium-review.googlesource.com/1181023 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Commit-Queue: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#55224}
This commit is contained in:
parent
f53e813e29
commit
72937ea4a8
4
BUILD.gn
4
BUILD.gn
@ -192,6 +192,10 @@ if (v8_check_microtasks_scopes_consistency == "") {
|
||||
|
||||
assert(!v8_enable_embedded_builtins || v8_use_snapshot,
|
||||
"Embedded builtins only work with snapshots")
|
||||
assert(
|
||||
v8_current_cpu != "x86" || !v8_enable_embedded_builtins ||
|
||||
!v8_untrusted_code_mitigations,
|
||||
"Embedded builtins on ia32 and untrusted code mitigations are incompatible")
|
||||
|
||||
assert(!v8_enable_embedded_bytecode_handlers || v8_enable_embedded_builtins,
|
||||
"Embedded bytecode handlers only work with embedded builtins")
|
||||
|
@ -314,6 +314,7 @@ bool Builtins::IsLazy(int index) {
|
||||
// static
|
||||
bool Builtins::IsIsolateIndependent(int index) {
|
||||
DCHECK(IsBuiltinId(index));
|
||||
#ifndef V8_TARGET_ARCH_IA32
|
||||
switch (index) {
|
||||
// TODO(jgruber): There's currently two blockers for moving
|
||||
// InterpreterEntryTrampoline into the binary:
|
||||
@ -332,6 +333,15 @@ bool Builtins::IsIsolateIndependent(int index) {
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
#else // V8_TARGET_ARCH_IA32
|
||||
// TODO(jgruber, v8:6666): Implement support.
|
||||
// ia32 is a work-in-progress. This will let us make builtins
|
||||
// isolate-independent one-by-one.
|
||||
switch (index) {
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#endif // V8_TARGET_ARCH_IA32
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,9 @@ void BuiltinsConstantsTableBuilder::Finalize() {
|
||||
isolate_->heap()->builtins_constants_table());
|
||||
DCHECK(isolate_->serializer_enabled());
|
||||
|
||||
DCHECK_LT(0, map_.size());
|
||||
// An empty map means there's nothing to do.
|
||||
if (map_.size() == 0) return;
|
||||
|
||||
Handle<FixedArray> table =
|
||||
isolate_->factory()->NewFixedArray(map_.size(), TENURED);
|
||||
|
||||
|
@ -303,6 +303,10 @@ class PipelineData {
|
||||
return jump_optimization_info_;
|
||||
}
|
||||
|
||||
const AssemblerOptions& assembler_options() const {
|
||||
return assembler_options_;
|
||||
}
|
||||
|
||||
CodeTracer* GetCodeTracer() const {
|
||||
return wasm_engine_ == nullptr ? isolate_->GetCodeTracer()
|
||||
: wasm_engine_->GetCodeTracer();
|
||||
@ -2402,6 +2406,17 @@ bool PipelineImpl::SelectInstructions(Linkage* linkage) {
|
||||
PoisoningMitigationLevel::kDontPoison) {
|
||||
AllocateRegisters(RegisterConfiguration::Poisoning(), call_descriptor,
|
||||
run_verifier);
|
||||
#if defined(V8_TARGET_ARCH_IA32) && defined(V8_EMBEDDED_BUILTINS)
|
||||
} else if (data_->assembler_options().isolate_independent_code) {
|
||||
// TODO(v8:6666): Extend support to all builtins and user code. Ensure that
|
||||
// it is mutually exclusive with the Poisoning configuration above; and that
|
||||
// it cooperates with restricted allocatable registers above.
|
||||
static_assert(kRootRegister == kSpeculationPoisonRegister);
|
||||
CHECK_IMPLIES(FLAG_embedded_builtins, !FLAG_branch_load_poisoning);
|
||||
CHECK_IMPLIES(FLAG_embedded_builtins, !FLAG_untrusted_code_mitigations);
|
||||
AllocateRegisters(RegisterConfiguration::PreserveRootIA32(),
|
||||
call_descriptor, run_verifier);
|
||||
#endif // V8_TARGET_ARCH_IA32
|
||||
} else {
|
||||
AllocateRegisters(RegisterConfiguration::Default(), call_descriptor,
|
||||
run_verifier);
|
||||
|
@ -38,6 +38,9 @@ constexpr Register kRuntimeCallFunctionRegister = ebx;
|
||||
constexpr Register kRuntimeCallArgCountRegister = eax;
|
||||
constexpr Register kWasmInstanceRegister = esi;
|
||||
|
||||
// TODO(v8:6666): Implement full support.
|
||||
constexpr Register kRootRegister = ebx;
|
||||
|
||||
// Convenience for platform-independent signatures. We do not normally
|
||||
// distinguish memory operands from other operands on ia32.
|
||||
typedef Operand MemOperand;
|
||||
|
@ -166,6 +166,55 @@ static base::LazyInstance<ArchDefaultPoisoningRegisterConfiguration,
|
||||
PoisoningRegisterConfigurationInitializer>::type
|
||||
kDefaultPoisoningRegisterConfiguration = LAZY_INSTANCE_INITIALIZER;
|
||||
|
||||
#if defined(V8_TARGET_ARCH_IA32) && defined(V8_EMBEDDED_BUILTINS)
|
||||
// Allocatable registers with the root register removed.
|
||||
// TODO(v8:6666): Once all builtins have been migrated, we could remove this
|
||||
// configuration and remove kRootRegister from ALLOCATABLE_GENERAL_REGISTERS
|
||||
// instead.
|
||||
class ArchPreserveRootIA32RegisterConfiguration : public RegisterConfiguration {
|
||||
public:
|
||||
ArchPreserveRootIA32RegisterConfiguration()
|
||||
: RegisterConfiguration(
|
||||
Register::kNumRegisters, DoubleRegister::kNumRegisters,
|
||||
kMaxAllocatableGeneralRegisterCount - 1,
|
||||
get_num_allocatable_double_registers(),
|
||||
InitializeGeneralRegisterCodes(), get_allocatable_double_codes(),
|
||||
kSimpleFPAliasing ? AliasingKind::OVERLAP : AliasingKind::COMBINE,
|
||||
kGeneralRegisterNames, kFloatRegisterNames, kDoubleRegisterNames,
|
||||
kSimd128RegisterNames) {}
|
||||
|
||||
private:
|
||||
static const int* InitializeGeneralRegisterCodes() {
|
||||
int filtered_index = 0;
|
||||
for (int i = 0; i < kMaxAllocatableGeneralRegisterCount; ++i) {
|
||||
if (kAllocatableGeneralCodes[i] != kRootRegister.code()) {
|
||||
allocatable_general_codes_[filtered_index] =
|
||||
kAllocatableGeneralCodes[i];
|
||||
filtered_index++;
|
||||
}
|
||||
}
|
||||
DCHECK_EQ(filtered_index, kMaxAllocatableGeneralRegisterCount - 1);
|
||||
return allocatable_general_codes_;
|
||||
}
|
||||
|
||||
static int
|
||||
allocatable_general_codes_[kMaxAllocatableGeneralRegisterCount - 1];
|
||||
};
|
||||
|
||||
int ArchPreserveRootIA32RegisterConfiguration::allocatable_general_codes_
|
||||
[kMaxAllocatableGeneralRegisterCount - 1];
|
||||
|
||||
struct PreserveRootIA32RegisterConfigurationInitializer {
|
||||
static void Construct(void* config) {
|
||||
new (config) ArchPreserveRootIA32RegisterConfiguration();
|
||||
}
|
||||
};
|
||||
|
||||
static base::LazyInstance<ArchPreserveRootIA32RegisterConfiguration,
|
||||
PreserveRootIA32RegisterConfigurationInitializer>::
|
||||
type kPreserveRootIA32RegisterConfiguration = LAZY_INSTANCE_INITIALIZER;
|
||||
#endif // defined(V8_TARGET_ARCH_IA32) && defined(V8_EMBEDDED_BUILTINS)
|
||||
|
||||
// RestrictedRegisterConfiguration uses the subset of allocatable general
|
||||
// registers the architecture support, which results into generating assembly
|
||||
// to use less registers. Currently, it's only used by RecordWrite code stub.
|
||||
@ -218,6 +267,12 @@ const RegisterConfiguration* RegisterConfiguration::Poisoning() {
|
||||
return &kDefaultPoisoningRegisterConfiguration.Get();
|
||||
}
|
||||
|
||||
#if defined(V8_TARGET_ARCH_IA32) && defined(V8_EMBEDDED_BUILTINS)
|
||||
const RegisterConfiguration* RegisterConfiguration::PreserveRootIA32() {
|
||||
return &kPreserveRootIA32RegisterConfiguration.Get();
|
||||
}
|
||||
#endif // defined(V8_TARGET_ARCH_IA32) && defined(V8_EMBEDDED_BUILTINS)
|
||||
|
||||
const RegisterConfiguration* RegisterConfiguration::RestrictGeneralRegisters(
|
||||
RegList registers) {
|
||||
int num = NumRegs(registers);
|
||||
|
@ -34,6 +34,9 @@ class V8_EXPORT_PRIVATE RegisterConfiguration {
|
||||
// Register configuration with reserved masking register.
|
||||
static const RegisterConfiguration* Poisoning();
|
||||
|
||||
// Register configuration with reserved root register on ia32.
|
||||
static const RegisterConfiguration* PreserveRootIA32();
|
||||
|
||||
static const RegisterConfiguration* RestrictGeneralRegisters(
|
||||
RegList registers);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user