diff options
author | 2016-01-15 09:35:13 +0000 | |
---|---|---|
committer | 2016-01-19 11:29:20 +0000 | |
commit | 65902e86b91f984061657bd8cacf239edb53c39d (patch) | |
tree | 42d2b7b9a4004b0b02c44df5f8dda14d51fb7366 /runtime/interpreter/interpreter_common.cc | |
parent | 14c2d9fd6fba4732d1a43e3288c818b8e0e049fa (diff) |
ART: Optimize out redundant NewInstances of String
NewInstance of String creates an empty String object before it is
replaced by the result of a StringFactory call (String.<init>). If
the empty object is never used prior to the call, it can be safely
removed (replaced with null in this case).
We do not remove the instruction if:
- it has a real use (comparison, instanceof, check-cast), or
- we are compiling with --debuggable and there is an environment use.
If removed and execution deoptimizes before the StringFactory call,
the interpreter will see String.<init> being called on a null object.
Since the verifier guarantees that the call was made on new-instance
in the input bytecode (b/26579108), the interpreter can safely assume
that it was optimized out rather than throw NullPointerException.
Results (all without --debuggable):
- boot.oat: 563/563 removed
- Google Maps: 480/480 removed
- Google Docs: 819/819 removed
Change-Id: I9fdfc50e9dea6299a7327f94327cdfd2b2538079
Diffstat (limited to 'runtime/interpreter/interpreter_common.cc')
-rw-r--r-- | runtime/interpreter/interpreter_common.cc | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 18fb0d8518..ecd4de9bd0 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -592,6 +592,10 @@ static inline bool DoCallCommon(ArtMethod* called_method, // // (at this point the ArtMethod has already been replaced, // so we just need to fix-up the arguments) + // + // Note that FindMethodFromCode in entrypoint_utils-inl.h was also special-cased + // to handle the compiler optimization of replacing `this` with null without + // throwing NullPointerException. uint32_t string_init_vreg_this = is_range ? vregC : arg[0]; if (UNLIKELY(string_init)) { DCHECK_GT(num_regs, 0u); // As the method is an instance method, there should be at least 1. |