Invoke static/direct dispatch change.
There was a subtle race in static/direct dispatch via the code and methods
table. This patch removes the table in preparation of architectures like
x86 which will more aggressively sink loads.
Removes unused fields, code.. Brings back resolved methods table
short-cut and associated fast paths to use this (such as in Proxy). Adds
a resolution method that is used as the trampoline for static and direct
methods.
Add source file and line number to Throwable::Dump.
MethodHelper knowledge of runtime methods.
Change-Id: Ieae1b74c24072e6327a5bb2cad466f04e3c46c4d
diff --git a/src/object.h b/src/object.h
index da8064f..29d8255 100644
--- a/src/object.h
+++ b/src/object.h
@@ -598,6 +598,10 @@
return OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_strings_);
}
+ static MemberOffset DexCacheResolvedMethodsOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_methods_);
+ }
+
static MemberOffset DexCacheResolvedTypesOffset() {
return OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_resolved_types_);
}
@@ -607,12 +611,12 @@
dex_cache_initialized_static_storage_);
}
+ ObjectArray<Method>* GetDexCacheResolvedMethods() const;
+ void SetDexCacheResolvedMethods(ObjectArray<Method>* new_dex_cache_methods);
+
ObjectArray<Class>* GetDexCacheResolvedTypes() const;
void SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_types);
- CodeAndDirectMethods* GetDexCacheCodeAndDirectMethods() const;
- void SetDexCacheCodeAndDirectMethods(CodeAndDirectMethods* new_value);
-
ObjectArray<StaticStorageBase>* GetDexCacheInitializedStaticStorage() const;
void SetDexCacheInitializedStaticStorage(ObjectArray<StaticStorageBase>* new_value);
@@ -764,7 +768,7 @@
void RegisterNative(Thread* self, const void* native_method);
- void UnregisterNative();
+ void UnregisterNative(Thread* self);
static MemberOffset NativeMethodOffset() {
return OFFSET_OF_OBJECT_MEMBER(Method, native_method_);
@@ -801,10 +805,6 @@
return OFFSET_OF_OBJECT_MEMBER(Method, invoke_stub_);
}
- static MemberOffset GetDexCacheCodeAndDirectMethodsOffset() {
- return OFFSET_OF_OBJECT_MEMBER(Method, dex_cache_code_and_direct_methods_);
- }
-
static MemberOffset GetMethodIndexOffset() {
return OFFSET_OF_OBJECT_MEMBER(Method, method_index_);
}
@@ -838,10 +838,23 @@
}
}
// Check that if we do think it is phony it looks like the callee save method
- DCHECK(!result || GetCoreSpillMask() != 0);
+ DCHECK(!result || GetDexMethodIndex() == DexFile::kDexNoIndex16);
return result;
}
+ bool IsResolutionMethod() const {
+ bool result = this == Runtime::Current()->GetResolutionMethod();
+ // Check that if we do think it is phony it looks like the resolution method
+ DCHECK(!result || GetDexMethodIndex() == DexFile::kDexNoIndex16);
+ return result;
+ }
+
+ // Is this a CalleSaveMethod or ResolutionMethod and therefore doesn't adhere to normal
+ // conventions for a method of managed code.
+ bool IsRuntimeMethod() const {
+ return GetDexMethodIndex() == DexFile::kDexNoIndex16;
+ }
+
// Converts a native PC to a dex PC. TODO: this is a no-op
// until we associate a PC mapping table with each method.
uint32_t ToDexPC(const uintptr_t pc) const;
@@ -871,10 +884,10 @@
Class* declaring_class_;
// short cuts to declaring_class_->dex_cache_ member for fast compiled code access
- CodeAndDirectMethods* dex_cache_code_and_direct_methods_;
+ ObjectArray<StaticStorageBase>* dex_cache_initialized_static_storage_;
// short cuts to declaring_class_->dex_cache_ member for fast compiled code access
- ObjectArray<StaticStorageBase>* dex_cache_initialized_static_storage_;
+ ObjectArray<Class>* dex_cache_resolved_methods_;
// short cuts to declaring_class_->dex_cache_ member for fast compiled code access
ObjectArray<Class>* dex_cache_resolved_types_;
@@ -917,6 +930,8 @@
//
// For abstract methods in an interface class, this is the offset of the method in
// "iftable_->Get(n)->GetMethodArray()".
+ //
+ // For static and direct methods this is the index in the direct methods table.
uint32_t method_index_;
// The target native method registered with this method