Stop interpreter from accessing code items of compiled code.
The ArtInterpreterToCompiledCodeBridge accesses the code item in a
number of places to handle argument marshalling. However, the code item
of a compiled method should have no need to be accessed by the runtime
at all, since the code has been compiled. By removing these accesses,
there is a drop in the memory footprint of the dex file, since these
code items remain untouched by the runtime.
Includes fixes for JIT and deopt.
For Maps:
Systrace vdex memory usage: 19.4/33.4MB -> 18.8/33.4MB
Dumpsys meminfo vdex PSS: 9371kB -> 9275kB
Bug: 35800981
Test: mm test-art-host
Change-Id: I3bf17f8866287d9a8f127c16da23bebb801456dc
diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc
index 54d45b1..090bac1 100644
--- a/runtime/method_handles.cc
+++ b/runtime/method_handles.cc
@@ -514,7 +514,15 @@
}
}
- PerformCall(self, code_item, shadow_frame.GetMethod(), first_dest_reg, new_shadow_frame, result);
+ bool use_interpreter_entrypoint = ClassLinker::ShouldUseInterpreterEntrypoint(
+ called_method, called_method->GetEntryPointFromQuickCompiledCode());
+ PerformCall(self,
+ code_item,
+ shadow_frame.GetMethod(),
+ first_dest_reg,
+ new_shadow_frame,
+ result,
+ use_interpreter_entrypoint);
if (self->IsExceptionPending()) {
return false;
}
@@ -602,12 +610,15 @@
new_shadow_frame->SetVRegReference(0, receiver.Get());
new_shadow_frame->SetVRegReference(1, sf.Get());
+ bool use_interpreter_entrypoint = ClassLinker::ShouldUseInterpreterEntrypoint(
+ called_method, called_method->GetEntryPointFromQuickCompiledCode());
PerformCall(self,
code_item,
shadow_frame.GetMethod(),
0 /* first destination register */,
new_shadow_frame,
- result);
+ result,
+ use_interpreter_entrypoint);
if (self->IsExceptionPending()) {
return false;
}
@@ -1091,7 +1102,15 @@
num_input_regs);
self->EndAssertNoThreadSuspension(old_cause);
- PerformCall(self, code_item, shadow_frame.GetMethod(), first_dest_reg, new_shadow_frame, result);
+ bool use_interpreter_entrypoint = ClassLinker::ShouldUseInterpreterEntrypoint(
+ called_method, called_method->GetEntryPointFromQuickCompiledCode());
+ PerformCall(self,
+ code_item,
+ shadow_frame.GetMethod(),
+ first_dest_reg,
+ new_shadow_frame,
+ result,
+ use_interpreter_entrypoint);
if (self->IsExceptionPending()) {
return false;
}