ART: Use reinterpret_cast{32,64}<> when appropriate.
And fix UnstartedRuntime checking for null arguments in all
functions where we now use reinterpret_cast32<>.
This is a follow-up to
https://android-review.googlesource.com/783607 .
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: Pixel 2 XL boots.
Test: m test-art-target-gtest
Test: testrunner.py --target --optimizing
Bug: 117427174
Change-Id: I58f8ad59f70e3fbb1d06aef419cd26555706fa65
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index b747225..f778bc5 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -8892,7 +8892,7 @@
self,
kDexFileIndexStart + 1));
DCHECK(h_long_array != nullptr);
- h_long_array->Set(kDexFileIndexStart, reinterpret_cast<intptr_t>(dex_file));
+ h_long_array->Set(kDexFileIndexStart, reinterpret_cast64<int64_t>(dex_file));
// Note that this creates a finalizable dalvik.system.DexFile object and a corresponding
// FinalizerReference which will never get cleaned up without a started runtime.
diff --git a/runtime/class_loader_context.cc b/runtime/class_loader_context.cc
index 832f1d7..4da0091 100644
--- a/runtime/class_loader_context.cc
+++ b/runtime/class_loader_context.cc
@@ -19,6 +19,7 @@
#include <android-base/parseint.h>
#include "art_field-inl.h"
+#include "base/casts.h"
#include "base/dchecked_vector.h"
#include "base/stl_util.h"
#include "class_linker.h"
@@ -474,8 +475,8 @@
int32_t long_array_size = long_array->GetLength();
// Index 0 from the long array stores the oat file. The dex files start at index 1.
for (int32_t j = 1; j < long_array_size; ++j) {
- const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
- long_array->GetWithoutChecks(j)));
+ const DexFile* cp_dex_file =
+ reinterpret_cast64<const DexFile*>(long_array->GetWithoutChecks(j));
if (cp_dex_file != nullptr && cp_dex_file->NumClassDefs() > 0) {
// TODO(calin): It's unclear why the dex files with no classes are skipped here and when
// cp_dex_file can be null.
diff --git a/runtime/imt_conflict_table.h b/runtime/imt_conflict_table.h
index 3586864..02b3be4 100644
--- a/runtime/imt_conflict_table.h
+++ b/runtime/imt_conflict_table.h
@@ -187,17 +187,17 @@
ArtMethod* GetMethod(size_t index, PointerSize pointer_size) const {
if (pointer_size == PointerSize::k64) {
- return reinterpret_cast<ArtMethod*>(static_cast<uintptr_t>(data64_[index]));
+ return reinterpret_cast64<ArtMethod*>(data64_[index]);
} else {
- return reinterpret_cast<ArtMethod*>(static_cast<uintptr_t>(data32_[index]));
+ return reinterpret_cast32<ArtMethod*>(data32_[index]);
}
}
void SetMethod(size_t index, PointerSize pointer_size, ArtMethod* method) {
if (pointer_size == PointerSize::k64) {
- data64_[index] = dchecked_integral_cast<uint64_t>(reinterpret_cast<uintptr_t>(method));
+ data64_[index] = reinterpret_cast64<uint64_t>(method);
} else {
- data32_[index] = dchecked_integral_cast<uint32_t>(reinterpret_cast<uintptr_t>(method));
+ data32_[index] = reinterpret_cast32<uint32_t>(method);
}
}
diff --git a/runtime/imtable.h b/runtime/imtable.h
index aa0a504..3c52fb8 100644
--- a/runtime/imtable.h
+++ b/runtime/imtable.h
@@ -21,6 +21,7 @@
#error IMT_SIZE not defined
#endif
+#include "base/casts.h"
#include "base/enums.h"
#include "base/macros.h"
#include "base/mutex.h"
@@ -46,10 +47,10 @@
uint8_t* ptr = AddressOfElement(index, pointer_size);
if (pointer_size == PointerSize::k32) {
uint32_t value = *reinterpret_cast<uint32_t*>(ptr);
- return reinterpret_cast<ArtMethod*>(value);
+ return reinterpret_cast32<ArtMethod*>(value);
} else {
uint64_t value = *reinterpret_cast<uint64_t*>(ptr);
- return reinterpret_cast<ArtMethod*>(value);
+ return reinterpret_cast64<ArtMethod*>(value);
}
}
@@ -57,11 +58,9 @@
DCHECK_LT(index, kSize);
uint8_t* ptr = AddressOfElement(index, pointer_size);
if (pointer_size == PointerSize::k32) {
- uintptr_t value = reinterpret_cast<uintptr_t>(method);
- DCHECK_EQ(static_cast<uint32_t>(value), value); // Check that we dont lose any non 0 bits.
- *reinterpret_cast<uint32_t*>(ptr) = static_cast<uint32_t>(value);
+ *reinterpret_cast<uint32_t*>(ptr) = reinterpret_cast32<uint32_t>(method);
} else {
- *reinterpret_cast<uint64_t*>(ptr) = reinterpret_cast<uint64_t>(method);
+ *reinterpret_cast<uint64_t*>(ptr) = reinterpret_cast64<uint64_t>(method);
}
}
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 6577726..60c8ef3 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -18,6 +18,7 @@
#include <cmath>
+#include "base/casts.h"
#include "base/enums.h"
#include "class_root.h"
#include "debugger.h"
@@ -584,10 +585,10 @@
for (uint32_t i = 0, e = shadow_frame->NumberOfVRegs(); i < e; ++i) {
if (shadow_frame->GetVRegReference(i) == existing) {
DCHECK_EQ(shadow_frame->GetVRegReference(i),
- reinterpret_cast<mirror::Object*>(static_cast<uint32_t>(shadow_frame->GetVReg(i))));
+ reinterpret_cast32<mirror::Object*>(shadow_frame->GetVReg(i)));
shadow_frame->SetVRegReference(i, result.GetL());
DCHECK_EQ(shadow_frame->GetVRegReference(i),
- reinterpret_cast<mirror::Object*>(static_cast<uint32_t>(shadow_frame->GetVReg(i))));
+ reinterpret_cast32<mirror::Object*>(shadow_frame->GetVReg(i)));
}
}
}
@@ -1445,7 +1446,7 @@
// If both register locations contains the same value, the register probably holds a reference.
// Note: As an optimization, non-moving collectors leave a stale reference value
// in the references array even after the original vreg was overwritten to a non-reference.
- if (src_value == reinterpret_cast<uintptr_t>(o.Ptr())) {
+ if (src_value == reinterpret_cast32<uint32_t>(o.Ptr())) {
new_shadow_frame->SetVRegReference(dest_reg, o);
} else {
new_shadow_frame->SetVReg(dest_reg, src_value);
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 4cd3782..38ecc5a 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -638,7 +638,7 @@
}
uint32_t args[1];
- args[0] = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_array.Get()));
+ args[0] = reinterpret_cast32<uint32_t>(h_array.Get());
EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
if (self->IsExceptionPending()) {
@@ -1691,14 +1691,21 @@
}
void UnstartedRuntime::UnstartedJNIVMRuntimeNewUnpaddedArray(
- Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
- uint32_t* args, JValue* result) {
+ Thread* self,
+ ArtMethod* method ATTRIBUTE_UNUSED,
+ mirror::Object* receiver ATTRIBUTE_UNUSED,
+ uint32_t* args,
+ JValue* result) {
int32_t length = args[1];
DCHECK_GE(length, 0);
- ObjPtr<mirror::Class> element_class = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
+ ObjPtr<mirror::Object> element_class = reinterpret_cast32<mirror::Object*>(args[0])->AsClass();
+ if (element_class == nullptr) {
+ AbortTransactionOrFail(self, "VMRuntime.newUnpaddedArray with null element_class.");
+ return;
+ }
Runtime* runtime = Runtime::Current();
ObjPtr<mirror::Class> array_class =
- runtime->GetClassLinker()->FindArrayClass(self, element_class);
+ runtime->GetClassLinker()->FindArrayClass(self, element_class->AsClass());
DCHECK(array_class != nullptr);
gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator();
result->SetL(mirror::Array::Alloc<true, true>(self,
@@ -1789,14 +1796,17 @@
receiver->NotifyAll(self);
}
-void UnstartedRuntime::UnstartedJNIStringCompareTo(
- Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver, uint32_t* args,
- JValue* result) {
- mirror::String* rhs = reinterpret_cast<mirror::Object*>(args[0])->AsString();
+void UnstartedRuntime::UnstartedJNIStringCompareTo(Thread* self,
+ ArtMethod* method ATTRIBUTE_UNUSED,
+ mirror::Object* receiver,
+ uint32_t* args,
+ JValue* result) {
+ ObjPtr<mirror::Object> rhs = reinterpret_cast32<mirror::Object*>(args[0]);
if (rhs == nullptr) {
- AbortTransactionOrFail(self, "String.compareTo with null object");
+ AbortTransactionOrFail(self, "String.compareTo with null object.");
+ return;
}
- result->SetI(receiver->AsString()->CompareTo(rhs));
+ result->SetI(receiver->AsString()->CompareTo(rhs->AsString()));
}
void UnstartedRuntime::UnstartedJNIStringIntern(
@@ -1854,9 +1864,16 @@
}
void UnstartedRuntime::UnstartedJNIUnsafeCompareAndSwapInt(
- Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
- mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
- mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
+ Thread* self,
+ ArtMethod* method ATTRIBUTE_UNUSED,
+ mirror::Object* receiver ATTRIBUTE_UNUSED,
+ uint32_t* args,
+ JValue* result) {
+ ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
+ if (obj == nullptr) {
+ AbortTransactionOrFail(self, "Unsafe.compareAndSwapInt with null object.");
+ return;
+ }
jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
jint expectedValue = args[3];
jint newValue = args[4];
@@ -1877,12 +1894,14 @@
result->SetZ(success ? JNI_TRUE : JNI_FALSE);
}
-void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(
- Thread* self, ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED,
- uint32_t* args, JValue* result) {
- mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
+void UnstartedRuntime::UnstartedJNIUnsafeGetIntVolatile(Thread* self,
+ ArtMethod* method ATTRIBUTE_UNUSED,
+ mirror::Object* receiver ATTRIBUTE_UNUSED,
+ uint32_t* args,
+ JValue* result) {
+ ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
if (obj == nullptr) {
- AbortTransactionOrFail(self, "Cannot access null object, retry at runtime.");
+ AbortTransactionOrFail(self, "Unsafe.compareAndSwapIntVolatile with null object.");
return;
}
@@ -1890,12 +1909,18 @@
result->SetI(obj->GetField32Volatile(MemberOffset(offset)));
}
-void UnstartedRuntime::UnstartedJNIUnsafePutObject(
- Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
- mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result ATTRIBUTE_UNUSED) {
- mirror::Object* obj = reinterpret_cast<mirror::Object*>(args[0]);
+void UnstartedRuntime::UnstartedJNIUnsafePutObject(Thread* self,
+ ArtMethod* method ATTRIBUTE_UNUSED,
+ mirror::Object* receiver ATTRIBUTE_UNUSED,
+ uint32_t* args,
+ JValue* result ATTRIBUTE_UNUSED) {
+ ObjPtr<mirror::Object> obj = reinterpret_cast32<mirror::Object*>(args[0]);
+ if (obj == nullptr) {
+ AbortTransactionOrFail(self, "Unsafe.putObject with null object.");
+ return;
+ }
jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
- mirror::Object* newValue = reinterpret_cast<mirror::Object*>(args[3]);
+ ObjPtr<mirror::Object> newValue = reinterpret_cast32<mirror::Object*>(args[3]);
if (Runtime::Current()->IsActiveTransaction()) {
obj->SetFieldObject<true>(MemberOffset(offset), newValue);
} else {
@@ -1904,18 +1929,32 @@
}
void UnstartedRuntime::UnstartedJNIUnsafeGetArrayBaseOffsetForComponentType(
- Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
- mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
- ObjPtr<mirror::Class> component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
- Primitive::Type primitive_type = component->GetPrimitiveType();
+ Thread* self,
+ ArtMethod* method ATTRIBUTE_UNUSED,
+ mirror::Object* receiver ATTRIBUTE_UNUSED,
+ uint32_t* args,
+ JValue* result) {
+ ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
+ if (component == nullptr) {
+ AbortTransactionOrFail(self, "Unsafe.getArrayBaseOffsetForComponentType with null component.");
+ return;
+ }
+ Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value());
}
void UnstartedRuntime::UnstartedJNIUnsafeGetArrayIndexScaleForComponentType(
- Thread* self ATTRIBUTE_UNUSED, ArtMethod* method ATTRIBUTE_UNUSED,
- mirror::Object* receiver ATTRIBUTE_UNUSED, uint32_t* args, JValue* result) {
- ObjPtr<mirror::Class> component = reinterpret_cast<mirror::Object*>(args[0])->AsClass();
- Primitive::Type primitive_type = component->GetPrimitiveType();
+ Thread* self,
+ ArtMethod* method ATTRIBUTE_UNUSED,
+ mirror::Object* receiver ATTRIBUTE_UNUSED,
+ uint32_t* args,
+ JValue* result) {
+ ObjPtr<mirror::Object> component = reinterpret_cast32<mirror::Object*>(args[0]);
+ if (component == nullptr) {
+ AbortTransactionOrFail(self, "Unsafe.getArrayIndexScaleForComponentType with null component.");
+ return;
+ }
+ Primitive::Type primitive_type = component->AsClass()->GetPrimitiveType();
result->SetI(Primitive::ComponentSize(primitive_type));
}
diff --git a/runtime/mirror/var_handle.cc b/runtime/mirror/var_handle.cc
index ba99a07..4391910 100644
--- a/runtime/mirror/var_handle.cc
+++ b/runtime/mirror/var_handle.cc
@@ -18,6 +18,7 @@
#include "array-inl.h"
#include "art_field-inl.h"
+#include "base/casts.h"
#include "class-inl.h"
#include "class_linker.h"
#include "class_root.h"
@@ -1680,8 +1681,7 @@
}
ArtField* FieldVarHandle::GetField() {
- uintptr_t opaque_field = static_cast<uintptr_t>(GetField64(ArtFieldOffset()));
- return reinterpret_cast<ArtField*>(opaque_field);
+ return reinterpret_cast64<ArtField*>(GetField64(ArtFieldOffset()));
}
bool FieldVarHandle::Access(AccessMode access_mode,
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 0d1fe44..36f9b1a 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -20,6 +20,7 @@
#include "android-base/stringprintf.h"
+#include "base/casts.h"
#include "base/file_utils.h"
#include "base/logging.h"
#include "base/os.h"
@@ -74,10 +75,10 @@
return false;
}
- oat_file = reinterpret_cast<const OatFile*>(static_cast<uintptr_t>(long_data[kOatFileIndex]));
+ oat_file = reinterpret_cast64<const OatFile*>(long_data[kOatFileIndex]);
dex_files.reserve(array_size - 1);
for (jsize i = kDexFileIndexStart; i < array_size; ++i) {
- dex_files.push_back(reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(long_data[i])));
+ dex_files.push_back(reinterpret_cast64<const DexFile*>(long_data[i]));
}
env->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array), long_data, JNI_ABORT);
@@ -99,9 +100,9 @@
return nullptr;
}
- long_data[kOatFileIndex] = reinterpret_cast<uintptr_t>(oat_file);
+ long_data[kOatFileIndex] = reinterpret_cast64<jlong>(oat_file);
for (size_t i = 0; i < vec.size(); ++i) {
- long_data[kDexFileIndexStart + i] = reinterpret_cast<uintptr_t>(vec[i].get());
+ long_data[kDexFileIndexStart + i] = reinterpret_cast64<jlong>(vec[i].get());
}
env->ReleaseLongArrayElements(long_array, long_data, 0);
diff --git a/runtime/runtime-inl.h b/runtime/runtime-inl.h
index 374591e..bde0d11 100644
--- a/runtime/runtime-inl.h
+++ b/runtime/runtime-inl.h
@@ -22,6 +22,7 @@
#include "arch/instruction_set.h"
#include "art_method.h"
#include "base/callee_save_type.h"
+#include "base/casts.h"
#include "entrypoints/quick/callee_save_frame.h"
#include "gc_root-inl.h"
#include "obj_ptr-inl.h"
@@ -82,7 +83,7 @@
inline ArtMethod* Runtime::GetCalleeSaveMethodUnchecked(CalleeSaveType type)
REQUIRES_SHARED(Locks::mutator_lock_) {
- return reinterpret_cast<ArtMethod*>(callee_save_methods_[static_cast<size_t>(type)]);
+ return reinterpret_cast64<ArtMethod*>(callee_save_methods_[static_cast<size_t>(type)]);
}
} // namespace art
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 0092b97..b51fc30 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -45,6 +45,7 @@
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/bit_utils.h"
+#include "base/casts.h"
#include "base/file_utils.h"
#include "base/memory_tool.h"
#include "base/mutex.h"
@@ -500,7 +501,7 @@
Thread* Thread::FromManagedThread(const ScopedObjectAccessAlreadyRunnable& soa,
ObjPtr<mirror::Object> thread_peer) {
ArtField* f = jni::DecodeArtField(WellKnownClasses::java_lang_Thread_nativePeer);
- Thread* result = reinterpret_cast<Thread*>(static_cast<uintptr_t>(f->GetLong(thread_peer)));
+ Thread* result = reinterpret_cast64<Thread*>(f->GetLong(thread_peer));
// Sanity check that if we have a result it is either suspended or we hold the thread_list_lock_
// to stop it from going away.
if (kIsDebugBuild) {
@@ -907,7 +908,7 @@
}
self->GetJniEnv()->SetLongField(thread_peer,
WellKnownClasses::java_lang_Thread_nativePeer,
- reinterpret_cast<jlong>(self));
+ reinterpret_cast64<jlong>(self));
return true;
};
return Attach(thread_name, as_daemon, set_peer_action);
@@ -949,8 +950,9 @@
Thread* self = this;
DCHECK_EQ(self, Thread::Current());
- env->SetLongField(peer.get(), WellKnownClasses::java_lang_Thread_nativePeer,
- reinterpret_cast<jlong>(self));
+ env->SetLongField(peer.get(),
+ WellKnownClasses::java_lang_Thread_nativePeer,
+ reinterpret_cast64<jlong>(self));
ScopedObjectAccess soa(self);
StackHandleScope<1> hs(self);
@@ -3567,8 +3569,8 @@
if (!m->IsNative() && !m->IsRuntimeMethod() && (!m->IsProxyMethod() || m->IsConstructor())) {
const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
DCHECK(method_header->IsOptimized());
- StackReference<mirror::Object>* vreg_base = reinterpret_cast<StackReference<mirror::Object>*>(
- reinterpret_cast<uintptr_t>(cur_quick_frame));
+ StackReference<mirror::Object>* vreg_base =
+ reinterpret_cast<StackReference<mirror::Object>*>(cur_quick_frame);
uintptr_t native_pc_offset = method_header->NativeQuickPcOffset(GetCurrentQuickFramePc());
CodeInfo code_info(method_header, kPrecise
? CodeInfo::DecodeFlags::AllTables // We will need dex register maps.