Skip to content

AOT produce the same code several timesΒ #60012

@jensjoha

Description

@jensjoha

Say I have this file

import 'dart:io';
import 'dart:typed_data';

void main() {
  File f = new File.fromUri(Platform.script);
  Uint8List bytes = f.readAsBytesSync();
  Reproduction reproduction = new Reproduction(bytes);
  reproduction.reproduce();
}

class Reproduction {
  final Uint8List bytes;
  final int bytesLengthMinusOne;
  int byteOffset = 0;
  Reproduction(this.bytes) : bytesLengthMinusOne = bytes.length - 1;

  @pragma('vm:unsafe:no-bounds-checks')
  int advance() {
    ++byteOffset;
    if (byteOffset > bytesLengthMinusOne) return -1;
    return bytes[byteOffset];
  }

  @pragma('vm:unsafe:no-bounds-checks')
  @pragma("vm:never-inline")
  int reproduce() {
    int localByteOffset = byteOffset;
    while (localByteOffset + 10 < bytesLengthMinusOne) {
      // Here we can access bytes without checks
      int next = bytes[++localByteOffset];
      if (tableLookup(next) &&
          tableLookup(next = bytes[++localByteOffset]) &&
          tableLookup(next = bytes[++localByteOffset]) &&
          tableLookup(next = bytes[++localByteOffset]) &&
          tableLookup(next = bytes[++localByteOffset]) &&
          tableLookup(next = bytes[++localByteOffset]) &&
          tableLookup(next = bytes[++localByteOffset]) &&
          tableLookup(next = bytes[++localByteOffset]) &&
          tableLookup(next = bytes[++localByteOffset]) &&
          tableLookup(next = bytes[++localByteOffset])) {
        continue;
      }
      // If we got here the latest value into next returned false.
      byteOffset = localByteOffset;
      return next;
    }

    // Less than 10 bytes left in stream.
    while (true) {
      int next = advance();
      if (next == -1 || !tableLookup(next)) {
        return next;
      }
    }
  }
}

@pragma("vm:prefer-inline")
bool tableLookup(int next) {
  const List<bool> tabel = [
    // format hack.
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, true, false, false, false,
    false, false, false, false, false, false, false, false,
    true, true, true, true, true, true, true, true,
    true, true, false, false, false, false, false, false,
    false, true, true, true, true, true, true, true,
    true, true, true, true, true, true, true, true,
    true, true, true, true, true, true, true, true,
    true, true, true, false, false, false, false, true,
    false, true, true, true, true, true, true, true,
    true, true, true, true, true, true, true, true,
    true, true, true, true, true, true, true, true,
    true, true, true, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false,
    // format hack.
  ];
  return tabel[next];
}

The aot compile produce code like this:

148: B23[target]:200
150:     ParallelMove r9 <- rax, rax <- rbx goto:202 B14
152: B22[target]:196
154:     ParallelMove r9 <- rax, rax <- rbx goto:198 B14
156: B21[target]:192
158:     ParallelMove r9 <- rax, rax <- rbx goto:194 B14
160: B20[target]:188
162:     ParallelMove r9 <- rax, rax <- rbx goto:190 B14
164: B19[target]:184
166:     ParallelMove r9 <- rax, rax <- rbx goto:186 B14
168: B18[target]:180
170:     ParallelMove r9 <- rax, rax <- rbx goto:182 B14

or disassembled:

        ;; B23
        ;; ParallelMove r9 <- rax, rax <- rbx goto:202 B14
0x7f884cbad868    4989c1                 movq r9,rax
0x7f884cbad86b    4889d8                 movq rax,rbx
0x7f884cbad86e    e953000000             jmp 0x00007f884cbad8c6
        ;; B22
        ;; ParallelMove r9 <- rax, rax <- rbx goto:198 B14
0x7f884cbad873    4989c1                 movq r9,rax
0x7f884cbad876    4889d8                 movq rax,rbx
0x7f884cbad879    e948000000             jmp 0x00007f884cbad8c6
        ;; B21
        ;; ParallelMove r9 <- rax, rax <- rbx goto:194 B14
0x7f884cbad87e    4989c1                 movq r9,rax
0x7f884cbad881    4889d8                 movq rax,rbx
0x7f884cbad884    e93d000000             jmp 0x00007f884cbad8c6
        ;; B20
        ;; ParallelMove r9 <- rax, rax <- rbx goto:190 B14
0x7f884cbad889    4989c1                 movq r9,rax
0x7f884cbad88c    4889d8                 movq rax,rbx
0x7f884cbad88f    e932000000             jmp 0x00007f884cbad8c6
        ;; B19
        ;; ParallelMove r9 <- rax, rax <- rbx goto:186 B14
0x7f884cbad894    4989c1                 movq r9,rax
0x7f884cbad897    4889d8                 movq rax,rbx
0x7f884cbad89a    e927000000             jmp 0x00007f884cbad8c6
        ;; B18
        ;; ParallelMove r9 <- rax, rax <- rbx goto:182 B14
0x7f884cbad89f    4989c1                 movq r9,rax
0x7f884cbad8a2    4889d8                 movq rax,rbx
0x7f884cbad8a5    e91c000000             jmp 0x00007f884cbad8c6

i.e. the same code copied 6 times which seems odd (to me).

/cc @mraleph

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3A lower priority bug or feature requestarea-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.triagedIssue has been triaged by sub teamtype-performanceIssue relates to performance or code size

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions