[subset-cff] Optimize op_str_t layout
diff --git a/src/hb-cff-interp-common.hh b/src/hb-cff-interp-common.hh
index e90207a..4967629 100644
--- a/src/hb-cff-interp-common.hh
+++ b/src/hb-cff-interp-common.hh
@@ -480,7 +480,11 @@
/* an operator prefixed by its operands in a byte string */
struct op_str_t
{
- hb_ubytes_t str;
+ /* This used to be a hb_ubytes_t. Using a pointer and length
+ * saves 8 bytes in the struct. */
+ const unsigned char *ptr = nullptr;
+ unsigned length = 0;
+
op_code_t op;
};
@@ -492,9 +496,9 @@
{
TRACE_SERIALIZE (this);
- HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length);
+ HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.length);
if (unlikely (!d)) return_trace (false);
- memcpy (d, &opstr.str[0], opstr.str.length);
+ memcpy (d, opstr.ptr, opstr.length);
return_trace (true);
}
};
@@ -518,7 +522,9 @@
{
VAL *val = values.push ();
val->op = op;
- val->str = str_ref.sub_array (opStart, str_ref.get_offset () - opStart);
+ auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart);
+ val->ptr = arr.arrayZ;
+ val->length = arr.length;
opStart = str_ref.get_offset ();
}
@@ -526,7 +532,9 @@
{
VAL *val = values.push (v);
val->op = op;
- val->str = str_ref.sub_array (opStart, str_ref.get_offset () - opStart);
+ auto arr = str_ref.sub_array (opStart, str_ref.get_offset () - opStart);
+ val->ptr = arr.arrayZ;
+ val->length = arr.length;
opStart = str_ref.get_offset ();
}
diff --git a/src/hb-subset-cff-common.hh b/src/hb-subset-cff-common.hh
index 1528985..69c9eb6 100644
--- a/src/hb-subset-cff-common.hh
+++ b/src/hb-subset-cff-common.hh
@@ -104,20 +104,20 @@
encode_byte (op);
}
- void copy_str (const hb_ubytes_t &str)
+ void copy_str (const unsigned char *str, unsigned length)
{
unsigned int offset = buff.length;
/* Manually resize buffer since faster. */
- if (likely ((signed) (buff.length + str.length) <= buff.allocated))
- buff.length += str.length;
- else if (unlikely (!buff.resize (offset + str.length)))
+ if (likely ((signed) (buff.length + length) <= buff.allocated))
+ buff.length += length;
+ else if (unlikely (!buff.resize (offset + length)))
return;
/* Since our strings are one or two bytes typically,
* this is faster than memcpy. */
- for (unsigned i = 0; i < str.length; i++)
- buff.arrayZ[i + offset] = str.arrayZ[i];
- // memcpy (buff.arrayZ + offset, &str[0], str.length);
+ for (unsigned i = 0; i < length; i++)
+ buff.arrayZ[i + offset] = str[i];
+ // memcpy (buff.arrayZ + offset, str, length);
}
bool is_error () const { return buff.in_error (); }
@@ -183,9 +183,9 @@
}
else
{
- HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length);
+ HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.length);
if (unlikely (!d)) return_trace (false);
- memcpy (d, &opstr.str[0], opstr.str.length);
+ memcpy (d, opstr.ptr, opstr.length);
}
return_trace (true);
}
@@ -883,7 +883,7 @@
break;
default:
- encoder.copy_str (opstr.str);
+ encoder.copy_str (opstr.ptr, opstr.length);
break;
}
}
diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc
index fbf1894..53b0ed2 100644
--- a/src/hb-subset-cff1.cc
+++ b/src/hb-subset-cff1.cc
@@ -167,9 +167,10 @@
* for supplement, the original byte string is copied along with the op code */
op_str_t supp_op;
supp_op.op = op;
- if ( unlikely (!(opstr.str.length >= opstr.last_arg_offset + 3)))
+ if ( unlikely (!(opstr.length >= opstr.last_arg_offset + 3)))
return_trace (false);
- supp_op.str = hb_ubytes_t (&opstr.str + opstr.last_arg_offset, opstr.str.length - opstr.last_arg_offset);
+ supp_op.ptr = opstr.ptr + opstr.last_arg_offset;
+ supp_op.length = opstr.length - opstr.last_arg_offset;
return_trace (UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::registry]) &&
UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::ordering]) &&
copy_opstr (c, supp_op));