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