Skip to content
Permalink
Browse files
Use variadic length encoding for repo-auth-type tag
Summary:
The original encoding makes all 1 byte repo-auth type to 2 byte and it affects jitting (T39617978).
This diff reduces number of bytes needed for repo-auth type in most cases.

We need to move high bit (`kRATPtrBit`(0x4000) and `kRATArrayDataBit`(0x8000)) to low before doing variadic length encoding.

Reviewed By: markw65

Differential Revision: D13912544

fbshipit-source-id: f7edd1df0e6697957ac7dccb49f1014ce7758027
  • Loading branch information
yujunglo authored and hhvm-bot committed Feb 4, 2019
1 parent 37bbcb5 commit 39b0daf8ad6e476343e5323eace3cd5f644d4f2f
Showing with 46 additions and 25 deletions.
  1. +18 −5 hphp/runtime/base/repo-auth-type-codec-inl.h
  2. +28 −20 hphp/runtime/base/repo-auth-type-codec.cpp
@@ -31,8 +31,18 @@ constexpr uint16_t kRATArrayDataBit = 0x8000;
ALWAYS_INLINE
size_t encodedRATSize(const unsigned char* pc) {
using T = RepoAuthType::Tag;
auto const rawTag = (static_cast<uint16_t>(*(pc + 1)) << 8) |
static_cast<uint16_t>(*pc);
uint16_t permutatedTag = static_cast<uint8_t>(*pc);
auto nextPcVal = *(pc + 1);
if (permutatedTag == 0xff) {
uint8_t tmp = static_cast<uint8_t>(nextPcVal);
assertx(tmp != 0xff);
permutatedTag = tmp + 0xff;
nextPcVal = *(pc + 2);
}
size_t tagSize = permutatedTag < 0xff ? 1 : 2;

// Move the kRATPtrBit(0x4000) and kRATArrayDataBit(0x8000) bit back
uint16_t rawTag = (permutatedTag >> 2) | (permutatedTag << 14);
bool const highBitSet = rawTag & kRATArrayDataBit;
auto const tag = static_cast<T>(rawTag & ~kRATArrayDataBit);
switch (tag) {
@@ -73,7 +83,7 @@ size_t encodedRATSize(const unsigned char* pc) {
case T::InitGen:
case T::Gen:
assertx(!highBitSet);
return 2;
return tagSize;
case T::SArr:
case T::OptSArr:
case T::Arr:
@@ -98,13 +108,16 @@ size_t encodedRATSize(const unsigned char* pc) {
case T::OptSKeyset:
case T::Keyset:
case T::OptKeyset:
return highBitSet ? 6 : 2;
if (highBitSet) {
return ((int8_t(nextPcVal) < 0) ? 4 : 1) + tagSize;
}
return tagSize;
case T::ExactObj:
case T::SubObj:
case T::OptExactObj:
case T::OptSubObj:
assertx(!highBitSet);
return 6;
return ((int8_t(nextPcVal) < 0) ? 4 : 1) + tagSize;
}
not_reached();
}
@@ -29,9 +29,15 @@ template <class LookupStr, class LookupArrayType>
RepoAuthType decodeRATImpl(const unsigned char*& pc, LookupStr lookupStr,
LookupArrayType lookupArrayType) {
using T = RepoAuthType::Tag;
auto const rawTagLower = static_cast<uint16_t>(*pc++);
auto const rawTagUpper = static_cast<uint16_t>(*pc++);
auto const rawTag = (rawTagUpper << 8) | rawTagLower;
uint16_t permutatedTag = static_cast<uint8_t>(*pc++);
if (permutatedTag == 0xff) {
uint8_t tmp = static_cast<uint8_t>(*pc++);
assertx(tmp != 0xff);
permutatedTag = tmp + 0xff;
}

// Move the kRATPtrBit(0x4000) and kRATArrayDataBit(0x8000) bit back
auto rawTag = (permutatedTag >> 2) | (permutatedTag << 14);
bool const highBitSet = rawTag & kRATArrayDataBit;
auto const tag = static_cast<T>(rawTag & ~kRATArrayDataBit);
switch (tag) {
@@ -99,9 +105,7 @@ RepoAuthType decodeRATImpl(const unsigned char*& pc, LookupStr lookupStr,
case T::Keyset:
case T::OptKeyset:
if (highBitSet) {
uint32_t id;
std::memcpy(&id, pc, sizeof id);
pc += sizeof id;
uint32_t id = decode_iva(pc);
auto const arr = lookupArrayType(id);
return RepoAuthType{tag, arr};
}
@@ -113,9 +117,7 @@ RepoAuthType decodeRATImpl(const unsigned char*& pc, LookupStr lookupStr,
case T::OptSubObj:
assertx(!highBitSet);
{
uint32_t id;
std::memcpy(&id, pc, sizeof id);
pc += sizeof id;
uint32_t id = decode_iva(pc);
const StringData* const clsName = lookupStr(id);
return RepoAuthType{tag, clsName};
}
@@ -142,6 +144,19 @@ RepoAuthType decodeRAT(const UnitEmitter& ue, const unsigned char*& pc) {
}

void encodeRAT(UnitEmitter& ue, RepoAuthType rat) {
auto rawTag = static_cast<uint16_t>(rat.tag());
if (rat.hasArrData()) rawTag |= kRATArrayDataBit;

// Move the kRATPtrBit(0x4000) and kRATArrayDataBit(0x8000) last
uint16_t permutatedTag = (rawTag << 2) | (rawTag >> 14);
if (permutatedTag >= 0xff) {
// Write a 0xff signal byte
ue.emitByte(static_cast<uint8_t>(0xff));
permutatedTag -= 0xff;
}
assertx(permutatedTag < 0xff);
ue.emitByte(static_cast<uint8_t>(permutatedTag));

using T = RepoAuthType::Tag;
switch (rat.tag()) {
case T::Uninit:
@@ -180,7 +195,6 @@ void encodeRAT(UnitEmitter& ue, RepoAuthType rat) {
case T::Ref:
case T::InitGen:
case T::Gen:
ue.emitInt16(static_cast<uint16_t>(rat.tag()));
break;

case T::SArr:
@@ -207,22 +221,16 @@ void encodeRAT(UnitEmitter& ue, RepoAuthType rat) {
case T::OptSKeyset:
case T::Keyset:
case T::OptKeyset:
{
auto tagByte = static_cast<uint16_t>(rat.tag());
if (rat.hasArrData()) tagByte |= kRATArrayDataBit;
ue.emitInt16(tagByte);
if (rat.hasArrData()) {
ue.emitInt32(rat.arrayId());
}
break;
if (rat.hasArrData()) {
ue.emitIVA(rat.arrayId());
}
break;

case T::ExactObj:
case T::SubObj:
case T::OptExactObj:
case T::OptSubObj:
ue.emitInt16(static_cast<uint16_t>(rat.tag()));
ue.emitInt32(ue.mergeLitstr(rat.clsName()));
ue.emitIVA(ue.mergeLitstr(rat.clsName()));
break;
}
}

0 comments on commit 39b0daf

Please sign in to comment.