summaryrefslogtreecommitdiffstats
path: root/runtime/entrypoints/quick
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-01-06 12:55:46 -0800
committerIan Rogers <irogers@google.com>2014-02-06 23:20:27 -0800
commitef7d42fca18c16fbaf103822ad16f23246e2905d (patch)
treec67eea52a349c2ea7f2c3bdda8e73933c05531a8 /runtime/entrypoints/quick
parent822115a225185d2896607eb08d70ce5c7099adef (diff)
downloadart-ef7d42fca18c16fbaf103822ad16f23246e2905d.zip
art-ef7d42fca18c16fbaf103822ad16f23246e2905d.tar.gz
art-ef7d42fca18c16fbaf103822ad16f23246e2905d.tar.bz2
Object model changes to support 64bit.
Modify mirror objects so that references between them use an ObjectReference value type rather than an Object* so that functionality to compress larger references can be captured in the ObjectRefererence implementation. ObjectReferences are 32bit and all other aspects of object layout remain as they are currently. Expand fields in objects holding pointers so they can hold 64bit pointers. Its expected the size of these will come down by improving where we hold compiler meta-data. Stub out x86_64 architecture specific runtime implementation. Modify OutputStream so that reads and writes are of unsigned quantities. Make the use of portable or quick code more explicit. Templatize AtomicInteger to support more than just int32_t as a type. Add missing, and fix issues relating to, missing annotalysis information on the mutator lock. Refactor and share implementations for array copy between System and uses elsewhere in the runtime. Fix numerous 64bit build issues. Change-Id: I1a5694c251a42c9eff71084dfdd4b51fff716822
Diffstat (limited to 'runtime/entrypoints/quick')
-rw-r--r--runtime/entrypoints/quick/quick_cast_entrypoints.cc3
-rw-r--r--runtime/entrypoints/quick/quick_dexcache_entrypoints.cc6
-rw-r--r--runtime/entrypoints/quick/quick_field_entrypoints.cc38
-rw-r--r--runtime/entrypoints/quick/quick_fillarray_entrypoints.cc2
-rw-r--r--runtime/entrypoints/quick/quick_invoke_entrypoints.cc24
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc12
6 files changed, 47 insertions, 38 deletions
diff --git a/runtime/entrypoints/quick/quick_cast_entrypoints.cc b/runtime/entrypoints/quick/quick_cast_entrypoints.cc
index ae53d6c..a6ab69b 100644
--- a/runtime/entrypoints/quick/quick_cast_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_cast_entrypoints.cc
@@ -20,8 +20,7 @@
namespace art {
// Assignable test for code, won't throw. Null and equality tests already performed
-extern "C" uint32_t artIsAssignableFromCode(const mirror::Class* klass,
- const mirror::Class* ref_class)
+extern "C" uint32_t artIsAssignableFromCode(mirror::Class* klass, mirror::Class* ref_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(klass != NULL);
DCHECK(ref_class != NULL);
diff --git a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
index 003047a..ab428a5 100644
--- a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
@@ -26,7 +26,7 @@
namespace art {
extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx,
- const mirror::ArtMethod* referrer,
+ mirror::ArtMethod* referrer,
Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -38,7 +38,7 @@ extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx,
}
extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx,
- const mirror::ArtMethod* referrer,
+ mirror::ArtMethod* referrer,
Thread* self, mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Called when method->dex_cache_resolved_types_[] misses.
@@ -47,7 +47,7 @@ extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx,
}
extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type_idx,
- const mirror::ArtMethod* referrer,
+ mirror::ArtMethod* referrer,
Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc
index 0a533bd..93ff7aa 100644
--- a/runtime/entrypoints/quick/quick_field_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc
@@ -26,7 +26,7 @@
namespace art {
extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx,
- const mirror::ArtMethod* referrer,
+ mirror::ArtMethod* referrer,
Thread* self, mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead,
@@ -43,7 +43,7 @@ extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx,
}
extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx,
- const mirror::ArtMethod* referrer,
+ mirror::ArtMethod* referrer,
Thread* self, mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead,
@@ -60,17 +60,17 @@ extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx,
}
extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx,
- const mirror::ArtMethod* referrer,
+ mirror::ArtMethod* referrer,
Thread* self, mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectRead,
- sizeof(mirror::Object*));
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != NULL)) {
return field->GetObj(field->GetDeclaringClass());
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
field = FindFieldFromCode<StaticObjectRead, true>(field_idx, referrer, self,
- sizeof(mirror::Object*));
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != NULL)) {
return field->GetObj(field->GetDeclaringClass());
}
@@ -78,7 +78,7 @@ extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx,
}
extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
- const mirror::ArtMethod* referrer, Thread* self,
+ mirror::ArtMethod* referrer, Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead,
@@ -101,7 +101,7 @@ extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object*
}
extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
- const mirror::ArtMethod* referrer, Thread* self,
+ mirror::ArtMethod* referrer, Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead,
@@ -124,18 +124,18 @@ extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object*
}
extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
- const mirror::ArtMethod* referrer,
+ mirror::ArtMethod* referrer,
Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectRead,
- sizeof(mirror::Object*));
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != NULL && obj != NULL)) {
return field->GetObj(obj);
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
field = FindFieldFromCode<InstanceObjectRead, true>(field_idx, referrer, self,
- sizeof(mirror::Object*));
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != NULL)) {
if (UNLIKELY(obj == NULL)) {
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
@@ -148,7 +148,7 @@ extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror:
}
extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value,
- const mirror::ArtMethod* referrer, Thread* self,
+ mirror::ArtMethod* referrer, Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite,
@@ -166,7 +166,7 @@ extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value,
return -1; // failure
}
-extern "C" int artSet64StaticFromCode(uint32_t field_idx, const mirror::ArtMethod* referrer,
+extern "C" int artSet64StaticFromCode(uint32_t field_idx, mirror::ArtMethod* referrer,
uint64_t new_value, Thread* self, mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite,
@@ -185,11 +185,11 @@ extern "C" int artSet64StaticFromCode(uint32_t field_idx, const mirror::ArtMetho
}
extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_value,
- const mirror::ArtMethod* referrer, Thread* self,
+ mirror::ArtMethod* referrer, Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
- sizeof(mirror::Object*));
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != NULL)) {
if (LIKELY(!FieldHelper(field).IsPrimitiveType())) {
field->SetObj(field->GetDeclaringClass(), new_value);
@@ -198,7 +198,7 @@ extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_v
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
field = FindFieldFromCode<StaticObjectWrite, true>(field_idx, referrer, self,
- sizeof(mirror::Object*));
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != NULL)) {
field->SetObj(field->GetDeclaringClass(), new_value);
return 0; // success
@@ -207,7 +207,7 @@ extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_v
}
extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint32_t new_value,
- const mirror::ArtMethod* referrer, Thread* self,
+ mirror::ArtMethod* referrer, Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
@@ -261,18 +261,18 @@ extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
mirror::Object* new_value,
- const mirror::ArtMethod* referrer, Thread* self,
+ mirror::ArtMethod* referrer, Thread* self,
mirror::ArtMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
- sizeof(mirror::Object*));
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != NULL && obj != NULL)) {
field->SetObj(obj, new_value);
return 0; // success
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
field = FindFieldFromCode<InstanceObjectWrite, true>(field_idx, referrer, self,
- sizeof(mirror::Object*));
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != NULL)) {
if (UNLIKELY(obj == NULL)) {
ThrowLocation throw_location = self->GetCurrentLocationForThrow();
diff --git a/runtime/entrypoints/quick/quick_fillarray_entrypoints.cc b/runtime/entrypoints/quick/quick_fillarray_entrypoints.cc
index ca0c92e..8dac750 100644
--- a/runtime/entrypoints/quick/quick_fillarray_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_fillarray_entrypoints.cc
@@ -56,7 +56,7 @@ extern "C" int artHandleFillArrayDataFromCode(mirror::Array* array,
return -1; // Error
}
uint32_t size_in_bytes = payload->element_count * payload->element_width;
- memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes);
+ memcpy(array->GetRawData(payload->element_width, 0), payload->data, size_in_bytes);
return 0; // Success
}
diff --git a/runtime/entrypoints/quick/quick_invoke_entrypoints.cc b/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
index 5a1b3e8..c081768 100644
--- a/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_invoke_entrypoints.cc
@@ -124,21 +124,23 @@ extern "C" uint64_t artInvokeInterfaceTrampoline(mirror::ArtMethod* interface_me
return 0; // Failure.
}
}
- const void* code = method->GetEntryPointFromCompiledCode();
+ const void* code = method->GetEntryPointFromQuickCompiledCode();
-#ifndef NDEBUG
// When we return, the caller will branch to this address, so it had better not be 0!
- if (UNLIKELY(code == NULL)) {
+ if (kIsDebugBuild && UNLIKELY(code == nullptr)) {
MethodHelper mh(method);
LOG(FATAL) << "Code was NULL in method: " << PrettyMethod(method)
<< " location: " << mh.GetDexFile().GetLocation();
}
-#endif
-
+#ifdef __LP64__
+ UNIMPLEMENTED(FATAL);
+ return 0;
+#else
uint32_t method_uint = reinterpret_cast<uint32_t>(method);
uint64_t code_uint = reinterpret_cast<uint32_t>(code);
uint64_t result = ((code_uint << 32) | method_uint);
return result;
+#endif
}
template<InvokeType type, bool access_check>
@@ -156,21 +158,23 @@ uint64_t artInvokeCommon(uint32_t method_idx, mirror::Object* this_object,
}
}
DCHECK(!self->IsExceptionPending());
- const void* code = method->GetEntryPointFromCompiledCode();
+ const void* code = method->GetEntryPointFromQuickCompiledCode();
-#ifndef NDEBUG
// When we return, the caller will branch to this address, so it had better not be 0!
- if (UNLIKELY(code == NULL)) {
+ if (kIsDebugBuild && UNLIKELY(code == NULL)) {
MethodHelper mh(method);
LOG(FATAL) << "Code was NULL in method: " << PrettyMethod(method)
<< " location: " << mh.GetDexFile().GetLocation();
}
-#endif
-
+#ifdef __LP64__
+ UNIMPLEMENTED(FATAL);
+ return 0;
+#else
uint32_t method_uint = reinterpret_cast<uint32_t>(method);
uint64_t code_uint = reinterpret_cast<uint32_t>(code);
uint64_t result = ((code_uint << 32) | method_uint);
return result;
+#endif
}
// Explicit template declarations of artInvokeCommon for all invoke types.
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index b589384..9f30190 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -97,6 +97,12 @@ class QuickArgumentVisitor {
#define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__LR_OFFSET 28
#define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 32
#define QUICK_STACK_ARG_SKIP 16
+#elif defined(__x86_64__)
+// TODO: implement and check these.
+#define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 8
+#define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__LR_OFFSET 56
+#define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 64
+#define QUICK_STACK_ARG_SKIP 32
#else
#error "Unsupported architecture"
#define QUICK_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 0
@@ -567,15 +573,15 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called,
SirtRef<mirror::Class> called_class(soa.Self(), called->GetDeclaringClass());
linker->EnsureInitialized(called_class, true, true);
if (LIKELY(called_class->IsInitialized())) {
- code = called->GetEntryPointFromCompiledCode();
+ code = called->GetEntryPointFromQuickCompiledCode();
} else if (called_class->IsInitializing()) {
if (invoke_type == kStatic) {
// Class is still initializing, go to oat and grab code (trampoline must be left in place
// until class is initialized to stop races between threads).
- code = linker->GetOatCodeFor(called);
+ code = linker->GetQuickOatCodeFor(called);
} else {
// No trampoline for non-static methods.
- code = called->GetEntryPointFromCompiledCode();
+ code = called->GetEntryPointFromQuickCompiledCode();
}
} else {
DCHECK(called_class->IsErroneous());