diff options
| author | 2017-03-02 16:41:35 -0800 | |
|---|---|---|
| committer | 2017-03-03 08:58:16 -0800 | |
| commit | 7bf90484a6f3774875291e506136345f0b488976 (patch) | |
| tree | 4a8517f40094fbf42c4225bb09f7d8f255fde4f9 /compiler/driver/compiler_driver.cc | |
| parent | 9e7078b3e5794f1b65f7e75ad110551906bf5f0d (diff) | |
ART: Resolve <clinit> strings in compiler driver
Resolve strings for <clinit> in classes that fail initialization.
This will move the data from the zygote heap into the image heap,
creating clean memory.
Increases the image size by XXX. However, at the same time decreases
the zygote heap by the same amount.
Bug: 34956610
Test: m
Test: m test-art-host
Test: Device boots
Change-Id: I5be41da8424d5de65c02a2aed1ac4d6113741876
Diffstat (limited to 'compiler/driver/compiler_driver.cc')
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 24439ae816..a5e4cb0877 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -2365,9 +2365,9 @@ class InitializeClassVisitor : public CompilationVisitor { } if (!success) { - // On failure, still intern strings references for static fields, as these will be - // created in the zygote. This is separated from the transaction code just above - // as we will allocate strings, so must be allowed to suspend. + // On failure, still intern strings of static fields and seen in <clinit>, as these + // will be created in the zygote. This is separated from the transaction code just + // above as we will allocate strings, so must be allowed to suspend. InternStrings(klass, class_loader); } } @@ -2396,6 +2396,7 @@ class InitializeClassVisitor : public CompilationVisitor { const DexFile::ClassDef* class_def = klass->GetClassDef(); ClassLinker* class_linker = manager_->GetClassLinker(); + // Check encoded final field values for strings and intern. annotations::RuntimeEncodedStaticFieldValueIterator value_it(*dex_file, &h_dex_cache, &class_loader, @@ -2409,6 +2410,29 @@ class InitializeClassVisitor : public CompilationVisitor { CHECK(resolved != nullptr); } } + + // Intern strings seen in <clinit>. + ArtMethod* clinit = klass->FindClassInitializer(class_linker->GetImagePointerSize()); + if (clinit != nullptr) { + const DexFile::CodeItem* code_item = clinit->GetCodeItem(); + DCHECK(code_item != nullptr); + const Instruction* inst = Instruction::At(code_item->insns_); + + const uint32_t insns_size = code_item->insns_size_in_code_units_; + for (uint32_t dex_pc = 0; dex_pc < insns_size;) { + if (inst->Opcode() == Instruction::CONST_STRING) { + ObjPtr<mirror::String> s = class_linker->ResolveString( + *dex_file, dex::StringIndex(inst->VRegB_21c()), h_dex_cache); + CHECK(s != nullptr); + } else if (inst->Opcode() == Instruction::CONST_STRING_JUMBO) { + ObjPtr<mirror::String> s = class_linker->ResolveString( + *dex_file, dex::StringIndex(inst->VRegB_31c()), h_dex_cache); + CHECK(s != nullptr); + } + dex_pc += inst->SizeInCodeUnits(); + inst = inst->Next(); + } + } } const ParallelCompilationManager* const manager_; |