[subset-cff] Optimize op_str_t layout

This commit is contained in:
Behdad Esfahbod 2022-11-21 21:37:38 -07:00
parent a750cb0128
commit 4f056b923a
3 changed files with 26 additions and 17 deletions

View File

@ -480,7 +480,11 @@ struct arg_stack_t : cff_stack_t<ARG, 513>
/* an operator prefixed by its operands in a byte string */ /* an operator prefixed by its operands in a byte string */
struct op_str_t 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; op_code_t op;
}; };
@ -492,9 +496,9 @@ struct op_serializer_t
{ {
TRACE_SERIALIZE (this); 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); if (unlikely (!d)) return_trace (false);
memcpy (d, &opstr.str[0], opstr.str.length); memcpy (d, opstr.ptr, opstr.length);
return_trace (true); return_trace (true);
} }
}; };
@ -518,7 +522,9 @@ struct parsed_values_t
{ {
VAL *val = values.push (); VAL *val = values.push ();
val->op = op; 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 (); opStart = str_ref.get_offset ();
} }
@ -526,7 +532,9 @@ struct parsed_values_t
{ {
VAL *val = values.push (v); VAL *val = values.push (v);
val->op = op; 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 (); opStart = str_ref.get_offset ();
} }

View File

@ -104,20 +104,20 @@ struct str_encoder_t
encode_byte (op); 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; unsigned int offset = buff.length;
/* Manually resize buffer since faster. */ /* Manually resize buffer since faster. */
if (likely ((signed) (buff.length + str.length) <= buff.allocated)) if (likely ((signed) (buff.length + length) <= buff.allocated))
buff.length += str.length; buff.length += length;
else if (unlikely (!buff.resize (offset + str.length))) else if (unlikely (!buff.resize (offset + length)))
return; return;
/* Since our strings are one or two bytes typically, /* Since our strings are one or two bytes typically,
* this is faster than memcpy. */ * this is faster than memcpy. */
for (unsigned i = 0; i < str.length; i++) for (unsigned i = 0; i < length; i++)
buff.arrayZ[i + offset] = str.arrayZ[i]; buff.arrayZ[i + offset] = str[i];
// memcpy (buff.arrayZ + offset, &str[0], str.length); // memcpy (buff.arrayZ + offset, str, length);
} }
bool is_error () const { return buff.in_error (); } bool is_error () const { return buff.in_error (); }
@ -183,9 +183,9 @@ struct cff_font_dict_op_serializer_t : op_serializer_t
} }
else else
{ {
HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length); HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.length);
if (unlikely (!d)) return_trace (false); if (unlikely (!d)) return_trace (false);
memcpy (d, &opstr.str[0], opstr.str.length); memcpy (d, opstr.ptr, opstr.length);
} }
return_trace (true); return_trace (true);
} }
@ -883,7 +883,7 @@ struct subr_subsetter_t
break; break;
default: default:
encoder.copy_str (opstr.str); encoder.copy_str (opstr.ptr, opstr.length);
break; break;
} }
} }

View File

@ -167,9 +167,10 @@ struct cff1_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<cff1_top_dic
* for supplement, the original byte string is copied along with the op code */ * for supplement, the original byte string is copied along with the op code */
op_str_t supp_op; op_str_t supp_op;
supp_op.op = 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); 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]) && return_trace (UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::registry]) &&
UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::ordering]) && UnsizedByteStr::serialize_int2 (c, mod.nameSIDs[name_dict_values_t::ordering]) &&
copy_opstr (c, supp_op)); copy_opstr (c, supp_op));