ART: Remove CompiledClass
Replace by direct storage of the class status, and modify accessor
to return boolean value of whether the item exits. Reduces RAM
requirements and allocations for dex2oat.
Test: m test-art-host
Change-Id: I6a80ac3d644c7fd0da167996ab991b6d2796a458
diff --git a/compiler/compiled_class.h b/compiler/compiled_class.h
deleted file mode 100644
index 06ce946..0000000
--- a/compiler/compiled_class.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_COMPILER_COMPILED_CLASS_H_
-#define ART_COMPILER_COMPILED_CLASS_H_
-
-#include "mirror/class.h"
-
-namespace art {
-
-class CompiledClass {
- public:
- explicit CompiledClass(mirror::Class::Status status) : status_(status) {}
- ~CompiledClass() {}
- mirror::Class::Status GetStatus() const {
- return status_;
- }
- void SetStatus(mirror::Class::Status status) {
- status_ = status;
- }
- private:
- mirror::Class::Status status_;
-};
-
-} // namespace art
-
-#endif // ART_COMPILER_COMPILED_CLASS_H_
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index a8ab7c6..c2d792d 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -36,7 +36,6 @@
#include "base/time_utils.h"
#include "base/timing_logger.h"
#include "class_linker-inl.h"
-#include "compiled_class.h"
#include "compiled_method.h"
#include "compiler.h"
#include "compiler_callbacks.h"
@@ -317,11 +316,6 @@
}
CompilerDriver::~CompilerDriver() {
- Thread* self = Thread::Current();
- {
- MutexLock mu(self, compiled_classes_lock_);
- STLDeleteValues(&compiled_classes_);
- }
compiled_methods_.Visit([this](const MethodReference& ref ATTRIBUTE_UNUSED,
CompiledMethod* method) {
if (method != nullptr) {
@@ -1978,8 +1972,7 @@
if (compiler_only_verifies) {
// Just update the compiled_classes_ map. The compiler doesn't need to resolve
// the type.
- compiled_classes_.Overwrite(
- ClassReference(dex_file, i), new CompiledClass(mirror::Class::kStatusVerified));
+ compiled_classes_.Overwrite(ClassReference(dex_file, i), mirror::Class::kStatusVerified);
} else {
// Update the class status, so later compilation stages know they don't need to verify
// the class.
@@ -2690,14 +2683,15 @@
<< method_ref.dex_file->PrettyMethod(method_ref.dex_method_index);
}
-CompiledClass* CompilerDriver::GetCompiledClass(ClassReference ref) const {
+bool CompilerDriver::GetCompiledClass(ClassReference ref, mirror::Class::Status* status) const {
+ DCHECK(status != nullptr);
MutexLock mu(Thread::Current(), compiled_classes_lock_);
- ClassTable::const_iterator it = compiled_classes_.find(ref);
+ ClassStateTable::const_iterator it = compiled_classes_.find(ref);
if (it == compiled_classes_.end()) {
- return nullptr;
+ return false;
}
- CHECK(it->second != nullptr);
- return it->second;
+ *status = it->second;
+ return true;
}
void CompilerDriver::RecordClassStatus(ClassReference ref, mirror::Class::Status status) {
@@ -2719,12 +2713,11 @@
MutexLock mu(Thread::Current(), compiled_classes_lock_);
auto it = compiled_classes_.find(ref);
if (it == compiled_classes_.end()) {
- CompiledClass* compiled_class = new CompiledClass(status);
- compiled_classes_.Overwrite(ref, compiled_class);
- } else if (status > it->second->GetStatus()) {
+ compiled_classes_.Overwrite(ref, status);
+ } else if (status > it->second) {
// Update the status if we now have a greater one. This happens with vdex,
// which records a class is verified, but does not resolve it.
- it->second->SetStatus(status);
+ it->second = status;
}
}
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index fbab9df..e0d97b7 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -56,7 +56,6 @@
} // namespace verifier
class BitVector;
-class CompiledClass;
class CompiledMethod;
class CompilerOptions;
class DexCompilationUnit;
@@ -164,7 +163,7 @@
std::unique_ptr<const std::vector<uint8_t>> CreateQuickResolutionTrampoline() const;
std::unique_ptr<const std::vector<uint8_t>> CreateQuickToInterpreterBridge() const;
- CompiledClass* GetCompiledClass(ClassReference ref) const
+ bool GetCompiledClass(ClassReference ref, mirror::Class::Status* status) const
REQUIRES(!compiled_classes_lock_);
CompiledMethod* GetCompiledMethod(MethodReference ref) const;
@@ -505,10 +504,10 @@
std::map<ClassReference, bool> requires_constructor_barrier_
GUARDED_BY(requires_constructor_barrier_lock_);
- typedef SafeMap<const ClassReference, CompiledClass*> ClassTable;
+ using ClassStateTable = SafeMap<const ClassReference, mirror::Class::Status>;
// All class references that this compiler has compiled.
mutable Mutex compiled_classes_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
- ClassTable compiled_classes_ GUARDED_BY(compiled_classes_lock_);
+ ClassStateTable compiled_classes_ GUARDED_BY(compiled_classes_lock_);
typedef AtomicMethodRefMap<CompiledMethod*> MethodTable;
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 17854fd..26ea39f 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -23,7 +23,6 @@
#include "art_method-inl.h"
#include "class_linker-inl.h"
#include "common_compiler_test.h"
-#include "compiled_class.h"
#include "dex_file.h"
#include "dex_file_types.h"
#include "gc/heap.h"
@@ -339,10 +338,11 @@
ASSERT_NE(klass, nullptr);
EXPECT_TRUE(klass->IsVerified());
- CompiledClass* compiled_class = compiler_driver_->GetCompiledClass(
- ClassReference(&klass->GetDexFile(), klass->GetDexTypeIndex().index_));
- ASSERT_NE(compiled_class, nullptr);
- EXPECT_EQ(compiled_class->GetStatus(), mirror::Class::kStatusVerified);
+ mirror::Class::Status status;
+ bool found = compiler_driver_->GetCompiledClass(
+ ClassReference(&klass->GetDexFile(), klass->GetDexTypeIndex().index_), &status);
+ ASSERT_TRUE(found);
+ EXPECT_EQ(status, mirror::Class::kStatusVerified);
}
};
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 6b5387a..9b22334 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -28,7 +28,6 @@
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
-#include "compiled_class.h"
#include "compiled_method.h"
#include "debug/method_debug_info.h"
#include "dex/verification_results.h"
@@ -712,17 +711,17 @@
bool EndClass() {
ClassReference class_ref(dex_file_, class_def_index_);
- CompiledClass* compiled_class = writer_->compiler_driver_->GetCompiledClass(class_ref);
mirror::Class::Status status;
- if (compiled_class != nullptr) {
- status = compiled_class->GetStatus();
- } else if (writer_->compiler_driver_->GetVerificationResults()->IsClassRejected(class_ref)) {
- // The oat class status is used only for verification of resolved classes,
- // so use kStatusErrorResolved whether the class was resolved or unresolved
- // during compile-time verification.
- status = mirror::Class::kStatusErrorResolved;
- } else {
- status = mirror::Class::kStatusNotReady;
+ bool found = writer_->compiler_driver_->GetCompiledClass(class_ref, &status);
+ if (!found) {
+ if (writer_->compiler_driver_->GetVerificationResults()->IsClassRejected(class_ref)) {
+ // The oat class status is used only for verification of resolved classes,
+ // so use kStatusErrorResolved whether the class was resolved or unresolved
+ // during compile-time verification.
+ status = mirror::Class::kStatusErrorResolved;
+ } else {
+ status = mirror::Class::kStatusNotReady;
+ }
}
writer_->oat_classes_.emplace_back(offset_,