Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84f0758b authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi
Browse files

[res] Optimize few functions for dtoh() as a noop

Given that right now our device on disk endianness is exactly
the same as the in-memory one, few functions can be optimized
into noops or raw memcpy

Bug: 319137634
Test: boot + atest libandroidfw_tests
Flag: EXEMPT performance optimization
Change-Id: I2f048feea7a93fb52434b128aa2905ebf1bb46cb
parent 9036882d
Loading
Loading
Loading
Loading
+33 −45
Original line number Diff line number Diff line
@@ -152,8 +152,7 @@ static void fill9patchOffsets(Res_png_9patch* patch) {
    patch->colorsOffset = patch->yDivsOffset + (patch->numYDivs * sizeof(int32_t));
}

void Res_value::copyFrom_dtoh(const Res_value& src)
{
void Res_value::copyFrom_dtoh_slow(const Res_value& src) {
  size = dtohs(src.size);
  res0 = src.res0;
  dataType = src.dataType;
@@ -2031,16 +2030,6 @@ status_t ResXMLTree::validateNode(const ResXMLTree_node* node) const
// --------------------------------------------------------------------
// --------------------------------------------------------------------

void ResTable_config::copyFromDeviceNoSwap(const ResTable_config& o) {
    const size_t size = dtohl(o.size);
    if (size >= sizeof(ResTable_config)) {
        *this = o;
    } else {
        memcpy(this, &o, size);
        memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);
    }
}

/* static */ size_t unpackLanguageOrRegion(const char in[2], const char base,
        char out[4]) {
  if (in[0] & 0x80) {
@@ -2105,8 +2094,7 @@ size_t ResTable_config::unpackRegion(char region[4]) const {
    return unpackLanguageOrRegion(this->country, '0', region);
}


void ResTable_config::copyFromDtoH(const ResTable_config& o) {
void ResTable_config::copyFromDtoH_slow(const ResTable_config& o) {
  copyFromDeviceNoSwap(o);
  size = sizeof(ResTable_config);
  mcc = dtohs(mcc);
@@ -2121,7 +2109,7 @@ void ResTable_config::copyFromDtoH(const ResTable_config& o) {
  screenHeightDp = dtohs(screenHeightDp);
}

void ResTable_config::swapHtoD() {
void ResTable_config::swapHtoD_slow() {
  size = htodl(size);
  mcc = htods(mcc);
  mnc = htods(mnc);
@@ -2145,7 +2133,7 @@ void ResTable_config::swapHtoD() {
    // systems should happen very infrequently (if at all.)
    // The comparison code relies on memcmp low-level optimizations that make it
    // more efficient than strncmp.
    const char emptyScript[sizeof(l.localeScript)] = {'\0', '\0', '\0', '\0'};
    static constexpr char emptyScript[sizeof(l.localeScript)] = {'\0', '\0', '\0', '\0'};
    const char *lScript = l.localeScriptWasComputed ? emptyScript : l.localeScript;
    const char *rScript = r.localeScriptWasComputed ? emptyScript : r.localeScript;

+16 −9
Original line number Diff line number Diff line
@@ -32,6 +32,10 @@ namespace android {
namespace util {

void ReadUtf16StringFromDevice(const uint16_t* src, size_t len, std::string* out) {
  static constexpr bool kDeviceEndiannessSame = dtohs(0x1001) == 0x1001;
  if constexpr (kDeviceEndiannessSame) {
    *out = Utf16ToUtf8({(const char16_t*)src, strnlen16((const char16_t*)src, len)});
  } else {
    char buf[5];
    while (*src && len != 0) {
      char16_t c = static_cast<char16_t>(dtohs(*src));
@@ -41,6 +45,7 @@ void ReadUtf16StringFromDevice(const uint16_t* src, size_t len, std::string* out
      --len;
    }
  }
}

std::u16string Utf8ToUtf16(StringPiece utf8) {
  ssize_t utf16_length =
@@ -63,8 +68,10 @@ std::string Utf16ToUtf8(StringPiece16 utf16) {
  }

  std::string utf8;
  utf8.resize(utf8_length);
  utf16_to_utf8(utf16.data(), utf16.length(), &*utf8.begin(), utf8_length + 1);
  utf8.resize_and_overwrite(utf8_length, [&utf16](char* data, size_t size) {
    utf16_to_utf8(utf16.data(), utf16.length(), data, size + 1);
    return size;
  });
  return utf8;
}

+42 −6
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@

namespace android {

constexpr const bool kDeviceEndiannessSame = dtohs(0x1001) == 0x1001;

constexpr const uint32_t kIdmapMagic = 0x504D4449u;
constexpr const uint32_t kIdmapCurrentVersion = 0x0000000Au;

@@ -408,7 +410,16 @@ struct Res_value
    typedef uint32_t data_type;
    data_type data;

    void copyFrom_dtoh(const Res_value& src);
    void copyFrom_dtoh(const Res_value& src) {
      if constexpr (kDeviceEndiannessSame) {
        *this = src;
      } else {
        copyFrom_dtoh_slow(src);
      }
    }

   private:
    void copyFrom_dtoh_slow(const Res_value& src);
};

/**
@@ -1254,11 +1265,32 @@ struct ResTable_config
    // Varies in length from 3 to 8 chars. Zero-filled value.
    char localeNumberingSystem[8];

    void copyFromDeviceNoSwap(const ResTable_config& o);
    void copyFromDeviceNoSwap(const ResTable_config& o) {
      const auto o_size = dtohl(o.size);
      if (o_size >= sizeof(ResTable_config)) [[likely]] {
        *this = o;
      } else {
        memcpy(this, &o, o_size);
        memset(((uint8_t*)this) + o_size, 0, sizeof(ResTable_config) - o_size);
      }
      this->size = sizeof(*this);
    }

    void copyFromDtoH(const ResTable_config& o);
    void copyFromDtoH(const ResTable_config& o) {
      if constexpr (kDeviceEndiannessSame) {
        copyFromDeviceNoSwap(o);
      } else {
        copyFromDtoH_slow(o);
      }
    }

    void swapHtoD();
    void swapHtoD() {
      if constexpr (kDeviceEndiannessSame) {
        ;  // noop
      } else {
        swapHtoD_slow();
      }
    }

    int compare(const ResTable_config& o) const;
    int compareLogical(const ResTable_config& o) const;
@@ -1384,6 +1416,10 @@ struct ResTable_config
    bool isBetterThanBeforeLocale(const ResTable_config& o, const ResTable_config* requested) const;

    String8 toString() const;

   private:
    void copyFromDtoH_slow(const ResTable_config& o);
    void swapHtoD_slow();
};

/**