summaryrefslogtreecommitdiff
path: root/runtime/mirror/class.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/mirror/class.cc')
-rw-r--r--runtime/mirror/class.cc24
1 files changed, 22 insertions, 2 deletions
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 96b3345fab..b60c5731ae 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -100,9 +100,21 @@ void Class::SetStatus(Handle<Class> h_this, Status new_status, Thread* self) {
}
static_assert(sizeof(Status) == sizeof(uint32_t), "Size of status not equal to uint32");
if (Runtime::Current()->IsActiveTransaction()) {
- h_this->SetField32Volatile<true>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status);
+ h_this->SetField32Volatile<true>(StatusOffset(), new_status);
} else {
- h_this->SetField32Volatile<false>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status);
+ h_this->SetField32Volatile<false>(StatusOffset(), new_status);
+ }
+
+ // Setting the object size alloc fast path needs to be after the status write so that if the
+ // alloc path sees a valid object size, we would know that it's initialized as long as it has a
+ // load-acquire/fake dependency.
+ if (new_status == kStatusInitialized && !h_this->IsVariableSize()) {
+ uint32_t object_size = RoundUp(h_this->GetObjectSize(), kObjectAlignment);
+ if (h_this->IsFinalizable()) {
+ // Finalizable objects must always go slow path.
+ object_size = std::numeric_limits<int32_t>::max();
+ }
+ h_this->SetObjectSizeAllocFastPath(object_size);
}
if (!class_linker_initialized) {
@@ -1209,5 +1221,13 @@ int32_t Class::GetInnerClassFlags(Handle<Class> h_this, int32_t default_value) {
return flags;
}
+void Class::SetObjectSizeAllocFastPath(uint32_t new_object_size) {
+ if (Runtime::Current()->IsActiveTransaction()) {
+ SetField32Volatile<true>(ObjectSizeAllocFastPathOffset(), new_object_size);
+ } else {
+ SetField32Volatile<false>(ObjectSizeAllocFastPathOffset(), new_object_size);
+ }
+}
+
} // namespace mirror
} // namespace art