blob: 5fcbc0dafb37f985f83ce0ff051f17c04d1ca528 [file] [log] [blame]
Rudi Horn74ba5fd2020-10-29 14:41:14 +00001// 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
5package com.android.tools.r8.horizontalclassmerging;
6
7import com.android.tools.r8.graph.AppView;
8import com.android.tools.r8.graph.DexEncodedField;
9import com.android.tools.r8.graph.DexField;
10import com.android.tools.r8.graph.DexItemFactory;
11import com.android.tools.r8.graph.DexProgramClass;
12import com.android.tools.r8.horizontalclassmerging.HorizontalClassMergerGraphLens.Builder;
13import java.util.LinkedHashMap;
14import java.util.Map;
15
16public class ClassStaticFieldsMerger {
Christoffer Quist Adamsen96da23c2021-06-25 09:51:30 +020017
Morten Krogh-Jespersen5366e0c2021-11-18 15:40:00 +010018 private final AppView<?> appView;
Rudi Horn74ba5fd2020-10-29 14:41:14 +000019 private final DexItemFactory dexItemFactory;
Christoffer Quist Adamsen96da23c2021-06-25 09:51:30 +020020 private final MergeGroup group;
21 private final Builder lensBuilder;
22
23 private final Map<DexField, DexEncodedField> targetFields = new LinkedHashMap<>();
Rudi Horn74ba5fd2020-10-29 14:41:14 +000024
25 public ClassStaticFieldsMerger(
Christoffer Quist Adamsen7730dbf2020-11-17 14:03:36 +010026 AppView<?> appView, HorizontalClassMergerGraphLens.Builder lensBuilder, MergeGroup group) {
Morten Krogh-Jespersen5366e0c2021-11-18 15:40:00 +010027 this.appView = appView;
Rudi Horn74ba5fd2020-10-29 14:41:14 +000028 this.dexItemFactory = appView.dexItemFactory();
Christoffer Quist Adamsen96da23c2021-06-25 09:51:30 +020029 this.group = group;
30 this.lensBuilder = lensBuilder;
Rudi Horn74ba5fd2020-10-29 14:41:14 +000031 }
32
Christoffer Quist Adamsen9b102a92020-11-25 15:41:33 +010033 private boolean isFresh(DexField fieldReference) {
Christoffer Quist Adamsen96da23c2021-06-25 09:51:30 +020034 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 Horn74ba5fd2020-10-29 14:41:14 +000044 }
45
46 private void addField(DexEncodedField field) {
47 DexField oldFieldReference = field.getReference();
Rudi Horn74ba5fd2020-10-29 14:41:14 +000048 DexField newFieldReference =
Christoffer Quist Adamsen0c050fb2021-06-21 11:56:45 +020049 dexItemFactory.createFreshFieldNameWithoutHolder(
50 group.getTarget().getType(),
51 field.getType(),
52 field.getName().toString(),
53 this::isFresh);
Rudi Horn74ba5fd2020-10-29 14:41:14 +000054
Morten Krogh-Jespersen5366e0c2021-11-18 15:40:00 +010055 field = field.toTypeSubstitutedField(appView, newFieldReference);
Rudi Horn74ba5fd2020-10-29 14:41:14 +000056 targetFields.put(newFieldReference, field);
57
Christoffer Quist Adamsen9b102a92020-11-25 15:41:33 +010058 lensBuilder.recordNewFieldSignature(oldFieldReference, newFieldReference);
Rudi Horn74ba5fd2020-10-29 14:41:14 +000059 }
60
61 public void addFields(DexProgramClass toMerge) {
Christoffer Quist Adamsen96da23c2021-06-25 09:51:30 +020062 toMerge.forEachStaticField(this::addField);
Rudi Horn74ba5fd2020-10-29 14:41:14 +000063 }
64
Christoffer Quist Adamsen96da23c2021-06-25 09:51:30 +020065 public void merge() {
66 group.getTarget().appendStaticFields(targetFields.values());
Rudi Horn74ba5fd2020-10-29 14:41:14 +000067 }
68}