From 86083f7cd118f3d6c757191e83b4e4abaabdc5d7 Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Fri, 27 Oct 2017 10:59:04 -0700 Subject: runtime: Bitstring implementation for subtype checking (4/4). Integrate the previous CLs into ART Runtime. Subsequent CLs to add optimizing compiler support. Use spare 24-bits from "Class#status_" field to implement faster subtype checking in the runtime. Does not incur any extra memory overhead, and (when in compiled code) this is always as fast or faster than the original check. The new subtype checking is O(1) of the form: src <: target := (*src).status >> #imm_target_mask == #imm_target_shifted Based on the original prototype CL by Zhengkai Wu: https://android-review.googlesource.com/#/c/platform/art/+/440996/ Test: art/test.py -b -j32 --host Bug: 64692057 Change-Id: Iec3c54af529055a7f6147eebe5611d9ecd46942b --- compiler/optimizing/code_generator_arm64.cc | 5 +++-- compiler/optimizing/code_generator_arm_vixl.cc | 2 +- compiler/optimizing/code_generator_mips.cc | 2 +- compiler/optimizing/code_generator_mips64.cc | 2 +- compiler/optimizing/code_generator_x86.cc | 2 +- compiler/optimizing/code_generator_x86_64.cc | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) (limited to 'compiler') diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index bee1c08a32..64f2e46895 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -2170,9 +2170,10 @@ void InstructionCodeGeneratorARM64::GenerateClassInitializationCheck(SlowPathCod // Even if the initialized flag is set, we need to ensure consistent memory ordering. // TODO(vixl): Let the MacroAssembler handle MemOperand. __ Add(temp, class_reg, status_offset); - __ Ldar(temp, HeapOperand(temp)); + __ Ldarb(temp, HeapOperand(temp)); __ Cmp(temp, mirror::Class::kStatusInitialized); - __ B(lt, slow_path->GetEntryLabel()); + __ B(ne, slow_path->GetEntryLabel()); + // Use Bne instead of Blt because ARM64 doesn't have Ldarsb. __ Bind(slow_path->GetExitLabel()); } diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index ec50ae24b4..c7e2640590 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -7254,7 +7254,7 @@ void InstructionCodeGeneratorARMVIXL::GenerateClassInitializationCheck( LoadClassSlowPathARMVIXL* slow_path, vixl32::Register class_reg) { UseScratchRegisterScope temps(GetVIXLAssembler()); vixl32::Register temp = temps.Acquire(); - GetAssembler()->LoadFromOffset(kLoadWord, + GetAssembler()->LoadFromOffset(kLoadSignedByte, temp, class_reg, mirror::Class::StatusOffset().Int32Value()); diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 9d0826f193..85177115eb 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -1983,7 +1983,7 @@ void CodeGeneratorMIPS::GenerateInvokeRuntime(int32_t entry_point_offset, bool d void InstructionCodeGeneratorMIPS::GenerateClassInitializationCheck(SlowPathCodeMIPS* slow_path, Register class_reg) { - __ LoadFromOffset(kLoadWord, TMP, class_reg, mirror::Class::StatusOffset().Int32Value()); + __ LoadFromOffset(kLoadSignedByte, TMP, class_reg, mirror::Class::StatusOffset().Int32Value()); __ LoadConst32(AT, mirror::Class::kStatusInitialized); __ Blt(TMP, AT, slow_path->GetEntryLabel()); // Even if the initialized flag is set, we need to ensure consistent memory ordering. diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 18986c7c5f..51601a147e 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -1820,7 +1820,7 @@ void CodeGeneratorMIPS64::GenerateInvokeRuntime(int32_t entry_point_offset) { void InstructionCodeGeneratorMIPS64::GenerateClassInitializationCheck(SlowPathCodeMIPS64* slow_path, GpuRegister class_reg) { - __ LoadFromOffset(kLoadWord, TMP, class_reg, mirror::Class::StatusOffset().Int32Value()); + __ LoadFromOffset(kLoadSignedByte, TMP, class_reg, mirror::Class::StatusOffset().Int32Value()); __ LoadConst32(AT, mirror::Class::kStatusInitialized); __ Bltc(TMP, AT, slow_path->GetEntryLabel()); // Even if the initialized flag is set, we need to ensure consistent memory ordering. diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 9ddbf73e69..7fb346582d 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -6210,7 +6210,7 @@ void InstructionCodeGeneratorX86::VisitClinitCheck(HClinitCheck* check) { void InstructionCodeGeneratorX86::GenerateClassInitializationCheck( SlowPathCode* slow_path, Register class_reg) { - __ cmpl(Address(class_reg, mirror::Class::StatusOffset().Int32Value()), + __ cmpb(Address(class_reg, mirror::Class::StatusOffset().Int32Value()), Immediate(mirror::Class::kStatusInitialized)); __ j(kLess, slow_path->GetEntryLabel()); __ Bind(slow_path->GetExitLabel()); diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 9372c676ed..1dd1c015f4 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -5401,7 +5401,7 @@ void ParallelMoveResolverX86_64::RestoreScratch(int reg) { void InstructionCodeGeneratorX86_64::GenerateClassInitializationCheck( SlowPathCode* slow_path, CpuRegister class_reg) { - __ cmpl(Address(class_reg, mirror::Class::StatusOffset().Int32Value()), + __ cmpb(Address(class_reg, mirror::Class::StatusOffset().Int32Value()), Immediate(mirror::Class::kStatusInitialized)); __ j(kLess, slow_path->GetEntryLabel()); __ Bind(slow_path->GetExitLabel()); -- cgit v1.2.3-59-g8ed1b