dex_cache_array_fixups_arm.cc revision b4536b7de576b20c74c612406c5d3132998075ef
1b4536b7de576b20c74c612406c5d3132998075efVladimir Marko/* 2b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * Copyright (C) 2015 The Android Open Source Project 3b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * 4b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * Licensed under the Apache License, Version 2.0 (the "License"); 5b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * you may not use this file except in compliance with the License. 6b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * You may obtain a copy of the License at 7b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * 8b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * http://www.apache.org/licenses/LICENSE-2.0 9b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * 10b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * Unless required by applicable law or agreed to in writing, software 11b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * distributed under the License is distributed on an "AS IS" BASIS, 12b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * See the License for the specific language governing permissions and 14b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * limitations under the License. 15b4536b7de576b20c74c612406c5d3132998075efVladimir Marko */ 16b4536b7de576b20c74c612406c5d3132998075efVladimir Marko 17b4536b7de576b20c74c612406c5d3132998075efVladimir Marko#include "dex_cache_array_fixups_arm.h" 18b4536b7de576b20c74c612406c5d3132998075efVladimir Marko 19b4536b7de576b20c74c612406c5d3132998075efVladimir Marko#include "base/arena_containers.h" 20b4536b7de576b20c74c612406c5d3132998075efVladimir Marko#include "utils/dex_cache_arrays_layout-inl.h" 21b4536b7de576b20c74c612406c5d3132998075efVladimir Marko 22b4536b7de576b20c74c612406c5d3132998075efVladimir Markonamespace art { 23b4536b7de576b20c74c612406c5d3132998075efVladimir Markonamespace arm { 24b4536b7de576b20c74c612406c5d3132998075efVladimir Marko 25b4536b7de576b20c74c612406c5d3132998075efVladimir Marko/** 26b4536b7de576b20c74c612406c5d3132998075efVladimir Marko * Finds instructions that need the dex cache arrays base as an input. 27b4536b7de576b20c74c612406c5d3132998075efVladimir Marko */ 28b4536b7de576b20c74c612406c5d3132998075efVladimir Markoclass DexCacheArrayFixupsVisitor : public HGraphVisitor { 29b4536b7de576b20c74c612406c5d3132998075efVladimir Marko public: 30b4536b7de576b20c74c612406c5d3132998075efVladimir Marko explicit DexCacheArrayFixupsVisitor(HGraph* graph) 31b4536b7de576b20c74c612406c5d3132998075efVladimir Marko : HGraphVisitor(graph), 32b4536b7de576b20c74c612406c5d3132998075efVladimir Marko dex_cache_array_bases_(std::less<const DexFile*>(), 33b4536b7de576b20c74c612406c5d3132998075efVladimir Marko // Attribute memory use to code generator. 34b4536b7de576b20c74c612406c5d3132998075efVladimir Marko graph->GetArena()->Adapter(kArenaAllocCodeGenerator)) {} 35b4536b7de576b20c74c612406c5d3132998075efVladimir Marko 36b4536b7de576b20c74c612406c5d3132998075efVladimir Marko private: 37b4536b7de576b20c74c612406c5d3132998075efVladimir Marko void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) OVERRIDE { 38b4536b7de576b20c74c612406c5d3132998075efVladimir Marko // If this is an invoke with PC-relative access to the dex cache methods array, 39b4536b7de576b20c74c612406c5d3132998075efVladimir Marko // we need to add the dex cache arrays base as the special input. 40b4536b7de576b20c74c612406c5d3132998075efVladimir Marko if (invoke->HasPcRelativeDexCache()) { 41b4536b7de576b20c74c612406c5d3132998075efVladimir Marko // Initialize base for target method dex file if needed. 42b4536b7de576b20c74c612406c5d3132998075efVladimir Marko MethodReference target_method = invoke->GetTargetMethod(); 43b4536b7de576b20c74c612406c5d3132998075efVladimir Marko HArmDexCacheArraysBase* base = GetOrCreateDexCacheArrayBase(invoke, *target_method.dex_file); 44b4536b7de576b20c74c612406c5d3132998075efVladimir Marko // Update the element offset in base. 45b4536b7de576b20c74c612406c5d3132998075efVladimir Marko DexCacheArraysLayout layout(kArmPointerSize, target_method.dex_file); 46b4536b7de576b20c74c612406c5d3132998075efVladimir Marko base->UpdateElementOffset(layout.MethodOffset(target_method.dex_method_index)); 47b4536b7de576b20c74c612406c5d3132998075efVladimir Marko // Add the special argument base to the method. 48b4536b7de576b20c74c612406c5d3132998075efVladimir Marko DCHECK(!invoke->HasCurrentMethodInput()); 49b4536b7de576b20c74c612406c5d3132998075efVladimir Marko invoke->AddSpecialInput(base); 50b4536b7de576b20c74c612406c5d3132998075efVladimir Marko } 51b4536b7de576b20c74c612406c5d3132998075efVladimir Marko } 52b4536b7de576b20c74c612406c5d3132998075efVladimir Marko 53b4536b7de576b20c74c612406c5d3132998075efVladimir Marko HArmDexCacheArraysBase* GetOrCreateDexCacheArrayBase(HInstruction* user, 54b4536b7de576b20c74c612406c5d3132998075efVladimir Marko const DexFile& dex_file) { 55b4536b7de576b20c74c612406c5d3132998075efVladimir Marko // Ensure we only initialize the pointer once for each dex file. 56b4536b7de576b20c74c612406c5d3132998075efVladimir Marko auto lb = dex_cache_array_bases_.lower_bound(&dex_file); 57b4536b7de576b20c74c612406c5d3132998075efVladimir Marko if (lb != dex_cache_array_bases_.end() && 58b4536b7de576b20c74c612406c5d3132998075efVladimir Marko !dex_cache_array_bases_.key_comp()(&dex_file, lb->first)) { 59b4536b7de576b20c74c612406c5d3132998075efVladimir Marko return lb->second; 60b4536b7de576b20c74c612406c5d3132998075efVladimir Marko } 61b4536b7de576b20c74c612406c5d3132998075efVladimir Marko 62b4536b7de576b20c74c612406c5d3132998075efVladimir Marko HGraph* graph = GetGraph(); 63b4536b7de576b20c74c612406c5d3132998075efVladimir Marko HBasicBlock* entry = graph->GetEntryBlock(); 64b4536b7de576b20c74c612406c5d3132998075efVladimir Marko HArmDexCacheArraysBase* base = new (graph->GetArena()) HArmDexCacheArraysBase(dex_file); 65b4536b7de576b20c74c612406c5d3132998075efVladimir Marko HInstruction* insert_pos = (user->GetBlock() == entry) ? user : entry->GetLastInstruction(); 66b4536b7de576b20c74c612406c5d3132998075efVladimir Marko entry->InsertInstructionBefore(base, insert_pos); 67b4536b7de576b20c74c612406c5d3132998075efVladimir Marko dex_cache_array_bases_.PutBefore(lb, &dex_file, base); 68b4536b7de576b20c74c612406c5d3132998075efVladimir Marko return base; 69b4536b7de576b20c74c612406c5d3132998075efVladimir Marko } 70b4536b7de576b20c74c612406c5d3132998075efVladimir Marko 71b4536b7de576b20c74c612406c5d3132998075efVladimir Marko using DexCacheArraysBaseMap = 72b4536b7de576b20c74c612406c5d3132998075efVladimir Marko ArenaSafeMap<const DexFile*, HArmDexCacheArraysBase*, std::less<const DexFile*>>; 73b4536b7de576b20c74c612406c5d3132998075efVladimir Marko DexCacheArraysBaseMap dex_cache_array_bases_; 74b4536b7de576b20c74c612406c5d3132998075efVladimir Marko}; 75b4536b7de576b20c74c612406c5d3132998075efVladimir Marko 76b4536b7de576b20c74c612406c5d3132998075efVladimir Markovoid DexCacheArrayFixups::Run() { 77b4536b7de576b20c74c612406c5d3132998075efVladimir Marko DexCacheArrayFixupsVisitor visitor(graph_); 78b4536b7de576b20c74c612406c5d3132998075efVladimir Marko visitor.VisitInsertionOrder(); 79b4536b7de576b20c74c612406c5d3132998075efVladimir Marko} 80b4536b7de576b20c74c612406c5d3132998075efVladimir Marko 81b4536b7de576b20c74c612406c5d3132998075efVladimir Marko} // namespace arm 82b4536b7de576b20c74c612406c5d3132998075efVladimir Marko} // namespace art 83