OSDN Git Service

Merge "ARM64 read barrier support for concurrent GC in Optimizing."
authorRoland Levillain <rpl@google.com>
Wed, 25 Nov 2015 17:05:40 +0000 (17:05 +0000)
committerGerrit Code Review <noreply-gerritcodereview@google.com>
Wed, 25 Nov 2015 17:05:40 +0000 (17:05 +0000)
1  2 
compiler/optimizing/code_generator_arm64.cc

@@@ -3202,26 -3694,42 +3696,46 @@@ void InstructionCodeGeneratorARM64::Vis
    if (cls->IsReferrersClass()) {
      DCHECK(!cls->CanCallRuntime());
      DCHECK(!cls->MustGenerateClinitCheck());
-     __ Ldr(out, MemOperand(current_method, ArtMethod::DeclaringClassOffset().Int32Value()));
+     uint32_t declaring_class_offset = ArtMethod::DeclaringClassOffset().Int32Value();
+     if (kEmitCompilerReadBarrier) {
+       // /* GcRoot<mirror::Class>* */ out = &(current_method->declaring_class_)
+       __ Add(out.X(), current_method.X(), declaring_class_offset);
+       // /* mirror::Class* */ out = out->Read()
+       codegen_->GenerateReadBarrierForRoot(cls, out_loc, out_loc);
+     } else {
+       // /* GcRoot<mirror::Class> */ out = current_method->declaring_class_
+       __ Ldr(out, MemOperand(current_method, declaring_class_offset));
+     }
    } else {
 -    DCHECK(cls->CanCallRuntime());
      MemberOffset resolved_types_offset = ArtMethod::DexCacheResolvedTypesOffset(kArm64PointerSize);
+     // /* GcRoot<mirror::Class>[] */ out =
+     //        current_method.ptr_sized_fields_->dex_cache_resolved_types_
      __ Ldr(out.X(), MemOperand(current_method, resolved_types_offset.Int32Value()));
-     __ Ldr(out, MemOperand(out.X(), CodeGenerator::GetCacheOffset(cls->GetTypeIndex())));
-     // TODO: We will need a read barrier here.
+     size_t cache_offset = CodeGenerator::GetCacheOffset(cls->GetTypeIndex());
+     if (kEmitCompilerReadBarrier) {
+       // /* GcRoot<mirror::Class>* */ out = &out[type_index]
+       __ Add(out.X(), out.X(), cache_offset);
+       // /* mirror::Class* */ out = out->Read()
+       codegen_->GenerateReadBarrierForRoot(cls, out_loc, out_loc);
+     } else {
+       // /* GcRoot<mirror::Class> */ out = out[type_index]
+       __ Ldr(out, MemOperand(out.X(), cache_offset));
+     }
  
 -    SlowPathCodeARM64* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM64(
 -        cls, cls, cls->GetDexPc(), cls->MustGenerateClinitCheck());
 -    codegen_->AddSlowPath(slow_path);
 -    __ Cbz(out, slow_path->GetEntryLabel());
 -    if (cls->MustGenerateClinitCheck()) {
 -      GenerateClassInitializationCheck(slow_path, out);
 -    } else {
 -      __ Bind(slow_path->GetExitLabel());
 +    if (!cls->IsInDexCache() || cls->MustGenerateClinitCheck()) {
 +      DCHECK(cls->CanCallRuntime());
 +      SlowPathCodeARM64* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM64(
 +          cls, cls, cls->GetDexPc(), cls->MustGenerateClinitCheck());
 +      codegen_->AddSlowPath(slow_path);
 +      if (!cls->IsInDexCache()) {
 +        __ Cbz(out, slow_path->GetEntryLabel());
 +      }
 +      if (cls->MustGenerateClinitCheck()) {
 +        GenerateClassInitializationCheck(slow_path, out);
 +      } else {
 +        __ Bind(slow_path->GetExitLabel());
 +      }
      }
    }
  }