• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2016, 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 package com.android.tools.r8.code;
5 
6 import com.android.tools.r8.graph.DexString;
7 import com.android.tools.r8.graph.OffsetToObjectMapping;
8 import java.nio.ByteBuffer;
9 import java.nio.ShortBuffer;
10 import java.util.ArrayList;
11 import java.util.List;
12 
13 public class InstructionFactory extends BaseInstructionFactory {
14 
15   private DexString highestSortingString = null;
16 
readFrom(ShortBufferBytecodeStream stream, OffsetToObjectMapping mapping)17   static private Instruction readFrom(ShortBufferBytecodeStream stream,
18       OffsetToObjectMapping mapping) {
19     int high = stream.nextByte();
20     int opcode = stream.nextByte();
21     return create(high, opcode, stream, mapping);
22   }
23 
readSequenceFrom(ByteBuffer buffer, int startIndex, int length, OffsetToObjectMapping mapping)24   public Instruction[] readSequenceFrom(ByteBuffer buffer, int startIndex, int length,
25       OffsetToObjectMapping mapping) {
26     return readSequenceFrom(buffer.asShortBuffer(), startIndex, length, mapping);
27   }
28 
readSequenceFrom(ShortBuffer buffer, int startIndex, int length, OffsetToObjectMapping mapping)29   public Instruction[] readSequenceFrom(ShortBuffer buffer, int startIndex, int length,
30       OffsetToObjectMapping mapping) {
31     ShortBufferBytecodeStream range =
32         new ShortBufferBytecodeStream(buffer, startIndex, length);
33     List<Instruction> insn = new ArrayList<>(length);
34     while (range.hasMore()) {
35       Instruction instruction = readFrom(range, mapping);
36       if (instruction instanceof ConstString) {
37         updateHighestSortingString(((ConstString) instruction).getString());
38       } else if (instruction instanceof ConstStringJumbo) {
39         updateHighestSortingString(((ConstStringJumbo) instruction).getString());
40       }
41       insn.add(instruction);
42     }
43     return insn.toArray(new Instruction[insn.size()]);
44   }
45 
getHighestSortingString()46   public DexString getHighestSortingString() {
47     return highestSortingString;
48   }
49 
updateHighestSortingString(DexString string)50   private void updateHighestSortingString(DexString string) {
51     if (highestSortingString == null || highestSortingString.slowCompareTo(string) < 0) {
52       highestSortingString = string;
53     }
54   }
55 
56   private static class ShortBufferBytecodeStream implements BytecodeStream {
57 
58     private final int length;
59     private final int startIndex;
60     private final ShortBuffer source;
61 
62     private int offset = 0;
63     private int nextByte;
64     private boolean cacheContainsValidByte = false;
65 
ShortBufferBytecodeStream(ShortBuffer source, int startIndex, int length)66     ShortBufferBytecodeStream(ShortBuffer source, int startIndex, int length) {
67       this.startIndex = startIndex;
68       this.length = length;
69       this.source = source;
70     }
71 
72     @Override
nextShort()73     public int nextShort() {
74       assert !cacheContainsValidByte : "Unread byte in cache.";
75       assert offset < length;
76       int result = source.get(startIndex + offset);
77       offset += 1;
78       return result;
79     }
80 
81     public int nextByte() {
82       if (cacheContainsValidByte) {
83         cacheContainsValidByte = false;
84         return nextByte;
85       } else {
86         int next = nextShort();
87         nextByte = next & 0xff;
88         cacheContainsValidByte = true;
89         return (next >> 8) & 0xff;
90       }
91     }
92 
93     @Override
hasMore()94     public boolean hasMore() {
95       return length - offset > 0;
96     }
97 
98     @Override
getOffset()99     public int getOffset() {
100       return offset;
101     }
102   }
103 }
104