diff options
author | 2016-01-12 16:03:16 +0000 | |
---|---|---|
committer | 2016-01-12 16:05:38 +0000 | |
commit | a3eca2d7300f35c66cf4b696d788a8b7ba74eb99 (patch) | |
tree | 18ea775d51bfc71d90407bd801e8b56fb5309868 | |
parent | 3da15f8b1097905e06a59149c3a4a9658cbb7d5e (diff) |
Do not leave intermediate addresses across Java calls.
bug:26472446
Change-Id: Ie4a9b5fe6f1d61a76c71eceaa2299fe55512c612
-rw-r--r-- | compiler/optimizing/nodes.cc | 13 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/nodes_arm64.h | 1 | ||||
-rw-r--r-- | compiler/optimizing/register_allocator.cc | 3 | ||||
-rw-r--r-- | test/562-no-intermediate/expected.txt | 0 | ||||
-rw-r--r-- | test/562-no-intermediate/info.txt | 2 | ||||
-rw-r--r-- | test/562-no-intermediate/src/Main.java | 27 |
7 files changed, 46 insertions, 4 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 6d4275d8a6..8de9700250 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -2146,10 +2146,7 @@ void HInvoke::SetIntrinsic(Intrinsics intrinsic, IntrinsicExceptions exceptions) { intrinsic_ = intrinsic; IntrinsicOptimizations opt(this); - if (needs_env_or_cache == kNoEnvironmentOrCache) { - opt.SetDoesNotNeedDexCache(); - opt.SetDoesNotNeedEnvironment(); - } + // Adjust method's side effects from intrinsic table. switch (side_effects) { case kNoSideEffects: SetSideEffects(SideEffects::None()); break; @@ -2157,6 +2154,14 @@ void HInvoke::SetIntrinsic(Intrinsics intrinsic, case kWriteSideEffects: SetSideEffects(SideEffects::AllWrites()); break; case kAllSideEffects: SetSideEffects(SideEffects::AllExceptGCDependency()); break; } + + if (needs_env_or_cache == kNoEnvironmentOrCache) { + opt.SetDoesNotNeedDexCache(); + opt.SetDoesNotNeedEnvironment(); + } else { + // If we need an environment, that means there will be a call, which can trigger GC. + SetSideEffects(GetSideEffects().Union(SideEffects::CanTriggerGC())); + } // Adjust method's exception status from intrinsic table. switch (exceptions) { case kNoThrow: SetCanThrow(false); break; diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index c06d164523..9a7dfd8abf 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1868,6 +1868,10 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { return false; } + virtual bool IsActualObject() const { + return GetType() == Primitive::kPrimNot; + } + void SetReferenceTypeInfo(ReferenceTypeInfo rti); ReferenceTypeInfo GetReferenceTypeInfo() const { diff --git a/compiler/optimizing/nodes_arm64.h b/compiler/optimizing/nodes_arm64.h index 18405f2623..445cdab191 100644 --- a/compiler/optimizing/nodes_arm64.h +++ b/compiler/optimizing/nodes_arm64.h @@ -107,6 +107,7 @@ class HArm64IntermediateAddress : public HExpression<2> { bool CanBeMoved() const OVERRIDE { return true; } bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { return true; } + bool IsActualObject() const OVERRIDE { return false; } HInstruction* GetBaseAddress() const { return InputAt(0); } HInstruction* GetOffset() const { return InputAt(1); } diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index d399bc2d7a..9a06d9be41 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -1677,6 +1677,7 @@ void RegisterAllocator::ConnectSiblings(LiveInterval* interval) { LocationSummary* locations = safepoint_position->GetLocations(); if ((current->GetType() == Primitive::kPrimNot) && current->GetParent()->HasSpillSlot()) { + DCHECK(interval->GetDefinedBy()->IsActualObject()) << interval->GetDefinedBy()->DebugName(); locations->SetStackBit(current->GetParent()->GetSpillSlot() / kVRegSize); } @@ -1689,6 +1690,8 @@ void RegisterAllocator::ConnectSiblings(LiveInterval* interval) { maximum_number_of_live_fp_registers_); } if (current->GetType() == Primitive::kPrimNot) { + DCHECK(interval->GetDefinedBy()->IsActualObject()) + << interval->GetDefinedBy()->DebugName(); locations->SetRegisterBit(source.reg()); } break; diff --git a/test/562-no-intermediate/expected.txt b/test/562-no-intermediate/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/562-no-intermediate/expected.txt diff --git a/test/562-no-intermediate/info.txt b/test/562-no-intermediate/info.txt new file mode 100644 index 0000000000..4f21aebd03 --- /dev/null +++ b/test/562-no-intermediate/info.txt @@ -0,0 +1,2 @@ +Regression test for optimizing, checking that there is no +intermediate address between a Java call. diff --git a/test/562-no-intermediate/src/Main.java b/test/562-no-intermediate/src/Main.java new file mode 100644 index 0000000000..3b74d6f269 --- /dev/null +++ b/test/562-no-intermediate/src/Main.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class Main { + + /// CHECK-START-ARM64: int Main.main(String[]) register_allocator (after) + /// CHECK-NOT: IntermediateAddress + public static void main(String[] args) { + array[index] += Math.cos(42); + } + + static int index = 0; + static double[] array = new double[2]; +} |