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.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.