summaryrefslogtreecommitdiff
path: root/runtime/art_method.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/art_method.cc')
-rw-r--r--runtime/art_method.cc32
1 files changed, 31 insertions, 1 deletions
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index c1279bf6b1..f4a5f233ff 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -367,7 +367,7 @@ const uint8_t* ArtMethod::GetQuickenedInfo() {
}
const OatQuickMethodHeader* ArtMethod::GetOatQuickMethodHeader(uintptr_t pc) {
- if (IsRuntimeMethod() || IsProxyMethod()) {
+ if (IsRuntimeMethod()) {
return nullptr;
}
@@ -381,6 +381,12 @@ const OatQuickMethodHeader* ArtMethod::GetOatQuickMethodHeader(uintptr_t pc) {
return nullptr;
}
+ if (existing_entry_point == GetQuickProxyInvokeHandler()) {
+ DCHECK(IsProxyMethod() && !IsConstructor());
+ // The proxy entry point does not have any method header.
+ return nullptr;
+ }
+
// Check whether the current entry point contains this pc.
if (!class_linker->IsQuickResolutionStub(existing_entry_point) &&
!class_linker->IsQuickToInterpreterBridge(existing_entry_point)) {
@@ -452,4 +458,28 @@ const OatQuickMethodHeader* ArtMethod::GetOatQuickMethodHeader(uintptr_t pc) {
return method_header;
}
+
+void ArtMethod::CopyFrom(ArtMethod* src, size_t image_pointer_size) {
+ memcpy(reinterpret_cast<void*>(this), reinterpret_cast<const void*>(src),
+ Size(image_pointer_size));
+ declaring_class_ = GcRoot<mirror::Class>(const_cast<ArtMethod*>(src)->GetDeclaringClass());
+
+ // If the entry point of the method we are copying from is from JIT code, we just
+ // put the entry point of the new method to interpreter. We could set the entry point
+ // to the JIT code, but this would require taking the JIT code cache lock to notify
+ // it, which we do not want at this level.
+ Runtime* runtime = Runtime::Current();
+ if (runtime->GetJit() != nullptr) {
+ if (runtime->GetJit()->GetCodeCache()->ContainsPc(GetEntryPointFromQuickCompiledCode())) {
+ SetEntryPointFromQuickCompiledCodePtrSize(GetQuickToInterpreterBridge(), image_pointer_size);
+ }
+ }
+ // Clear the profiling info for the same reasons as the JIT code.
+ if (!src->IsNative()) {
+ SetProfilingInfoPtrSize(nullptr, image_pointer_size);
+ }
+ // Clear hotness to let the JIT properly decide when to compile this method.
+ hotness_count_ = 0;
+}
+
} // namespace art