Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 1 | // Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file |
| 2 | // for details. All rights reserved. Use of this source code is governed by a |
| 3 | // BSD-style license that can be found in the LICENSE file. |
| 4 | |
| 5 | package com.android.tools.r8.horizontalclassmerging; |
| 6 | |
| 7 | import com.android.tools.r8.graph.AppView; |
| 8 | import com.android.tools.r8.graph.DexEncodedField; |
| 9 | import com.android.tools.r8.graph.DexField; |
| 10 | import com.android.tools.r8.graph.DexItemFactory; |
| 11 | import com.android.tools.r8.graph.DexProgramClass; |
| 12 | import com.android.tools.r8.horizontalclassmerging.HorizontalClassMergerGraphLens.Builder; |
| 13 | import java.util.LinkedHashMap; |
| 14 | import java.util.Map; |
| 15 | |
| 16 | public class ClassStaticFieldsMerger { |
Christoffer Quist Adamsen | 96da23c | 2021-06-25 09:51:30 +0200 | [diff] [blame] | 17 | |
Morten Krogh-Jespersen | 5366e0c | 2021-11-18 15:40:00 +0100 | [diff] [blame] | 18 | private final AppView<?> appView; |
Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 19 | private final DexItemFactory dexItemFactory; |
Christoffer Quist Adamsen | 96da23c | 2021-06-25 09:51:30 +0200 | [diff] [blame] | 20 | private final MergeGroup group; |
| 21 | private final Builder lensBuilder; |
| 22 | |
| 23 | private final Map<DexField, DexEncodedField> targetFields = new LinkedHashMap<>(); |
Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 24 | |
| 25 | public ClassStaticFieldsMerger( |
Christoffer Quist Adamsen | 7730dbf | 2020-11-17 14:03:36 +0100 | [diff] [blame] | 26 | AppView<?> appView, HorizontalClassMergerGraphLens.Builder lensBuilder, MergeGroup group) { |
Morten Krogh-Jespersen | 5366e0c | 2021-11-18 15:40:00 +0100 | [diff] [blame] | 27 | this.appView = appView; |
Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 28 | this.dexItemFactory = appView.dexItemFactory(); |
Christoffer Quist Adamsen | 96da23c | 2021-06-25 09:51:30 +0200 | [diff] [blame] | 29 | this.group = group; |
| 30 | this.lensBuilder = lensBuilder; |
Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 31 | } |
| 32 | |
Christoffer Quist Adamsen | 9b102a9 | 2020-11-25 15:41:33 +0100 | [diff] [blame] | 33 | private boolean isFresh(DexField fieldReference) { |
Christoffer Quist Adamsen | 96da23c | 2021-06-25 09:51:30 +0200 | [diff] [blame] | 34 | if (group.getTarget().lookupField(fieldReference) != null) { |
| 35 | // The target class has an instance or static field with the given reference. |
| 36 | return false; |
| 37 | } |
| 38 | if (targetFields.containsKey(fieldReference)) { |
| 39 | // We have already committed another static field from a source class in the merge group to |
| 40 | // the given field reference (but the field is not yet added to the target class). |
| 41 | return false; |
| 42 | } |
| 43 | return true; |
Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 44 | } |
| 45 | |
| 46 | private void addField(DexEncodedField field) { |
| 47 | DexField oldFieldReference = field.getReference(); |
Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 48 | DexField newFieldReference = |
Christoffer Quist Adamsen | 0c050fb | 2021-06-21 11:56:45 +0200 | [diff] [blame] | 49 | dexItemFactory.createFreshFieldNameWithoutHolder( |
| 50 | group.getTarget().getType(), |
| 51 | field.getType(), |
| 52 | field.getName().toString(), |
| 53 | this::isFresh); |
Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 54 | |
Morten Krogh-Jespersen | 5366e0c | 2021-11-18 15:40:00 +0100 | [diff] [blame] | 55 | field = field.toTypeSubstitutedField(appView, newFieldReference); |
Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 56 | targetFields.put(newFieldReference, field); |
| 57 | |
Christoffer Quist Adamsen | 9b102a9 | 2020-11-25 15:41:33 +0100 | [diff] [blame] | 58 | lensBuilder.recordNewFieldSignature(oldFieldReference, newFieldReference); |
Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 59 | } |
| 60 | |
| 61 | public void addFields(DexProgramClass toMerge) { |
Christoffer Quist Adamsen | 96da23c | 2021-06-25 09:51:30 +0200 | [diff] [blame] | 62 | toMerge.forEachStaticField(this::addField); |
Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 63 | } |
| 64 | |
Christoffer Quist Adamsen | 96da23c | 2021-06-25 09:51:30 +0200 | [diff] [blame] | 65 | public void merge() { |
| 66 | group.getTarget().appendStaticFields(targetFields.values()); |
Rudi Horn | 74ba5fd | 2020-10-29 14:41:14 +0000 | [diff] [blame] | 67 | } |
| 68 | } |