[repacker] Add additional splitting spaces test.

Fix issues it uncovered.
pull/3248/head
Garret Rieger 3 years ago
parent 6265663de4
commit 7883b7ed95
  1. 11
      src/hb-repacker.hh
  2. 125
      src/test-repacker.cc

@ -474,7 +474,7 @@ struct graph_t
;
remap_obj_indices (index_map, new_subgraph);
remap_obj_indices (index_map, parents.iter ());
remap_obj_indices (index_map, parents.iter (), true);
// Update roots set with new indices as needed.
unsigned next = HB_SET_VALUE_INVALID;
@ -482,7 +482,6 @@ struct graph_t
{
if (index_map.has (next))
{
printf ("Updated root %u to %u.\n", next, index_map[next]);
roots.del (next);
roots.add (index_map[next]);
}
@ -752,8 +751,12 @@ struct graph_t
unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const
{
unsigned count = 0;
hb_set_t visited;
for (unsigned p : vertices_[node_idx].parents)
{
if (visited.has (p)) continue;
visited.add (p);
for (const auto& l : vertices_[p].obj.links)
{
if (l.objidx == node_idx && l.width == 4 && !l.is_signed)
@ -936,7 +939,8 @@ struct graph_t
*/
template<typename Iterator, hb_requires (hb_is_iterator (Iterator))>
void remap_obj_indices (const hb_hashmap_t<unsigned, unsigned>& id_map,
Iterator subgraph)
Iterator subgraph,
bool only_wide = false)
{
if (!id_map) return;
for (unsigned i : subgraph)
@ -945,6 +949,7 @@ struct graph_t
{
auto& link = vertices_[i].obj.links[j];
if (!id_map.has (link.objidx)) continue;
if (only_wide && !(link.width == 4 && !link.is_signed)) continue;
reassign_link (link, i, id_map[link.objidx]);
}

@ -515,6 +515,40 @@ populate_serializer_with_split_spaces (hb_serialize_context_t* c)
c->end_serialize();
}
static void
populate_serializer_with_split_spaces_2 (hb_serialize_context_t* c)
{
// Overflow needs to be resolved by splitting the single space
std::string large_string(70000, 'a');
c->start_serialize<char> ();
unsigned obj_f = add_object ("f", 1, c);
start_object (large_string.c_str(), 40000, c);
add_offset (obj_f, c);
unsigned obj_d = c->pop_pack (false);
start_object (large_string.c_str(), 40000, c);
add_offset (obj_f, c);
unsigned obj_e = c->pop_pack (false);
start_object ("b", 1, c);
add_offset (obj_d, c);
unsigned obj_b = c->pop_pack (false);
start_object ("c", 1, c);
add_offset (obj_e, c);
unsigned obj_c = c->pop_pack (false);
start_object ("a", 1, c);
add_offset (obj_b, c);
add_wide_offset (obj_b, c);
add_wide_offset (obj_c, c);
c->pop_pack (false);
c->end_serialize();
}
static void
populate_serializer_with_split_spaces_expected (hb_serialize_context_t* c)
{
@ -551,6 +585,60 @@ populate_serializer_with_split_spaces_expected (hb_serialize_context_t* c)
c->end_serialize();
}
static void
populate_serializer_with_split_spaces_expected_2 (hb_serialize_context_t* c)
{
// Overflow needs to be resolved by splitting the single space
std::string large_string(70000, 'a');
c->start_serialize<char> ();
// Space 2
unsigned obj_f_double_prime = add_object ("f", 1, c);
start_object (large_string.c_str(), 40000, c);
add_offset (obj_f_double_prime, c);
unsigned obj_d_prime = c->pop_pack (false);
start_object ("b", 1, c);
add_offset (obj_d_prime, c);
unsigned obj_b_prime = c->pop_pack (false);
// Space 1
unsigned obj_f_prime = add_object ("f", 1, c);
start_object (large_string.c_str(), 40000, c);
add_offset (obj_f_prime, c);
unsigned obj_e = c->pop_pack (false);
start_object ("c", 1, c);
add_offset (obj_e, c);
unsigned obj_c = c->pop_pack (false);
// Space 0
unsigned obj_f = add_object ("f", 1, c);
start_object (large_string.c_str(), 40000, c);
add_offset (obj_f, c);
unsigned obj_d = c->pop_pack (false);
start_object ("b", 1, c);
add_offset (obj_d, c);
unsigned obj_b = c->pop_pack (false);
// Root
start_object ("a", 1, c);
add_offset (obj_b, c);
add_wide_offset (obj_b_prime, c);
add_wide_offset (obj_c, c);
c->pop_pack (false);
c->end_serialize();
}
static void
populate_serializer_complex_1 (hb_serialize_context_t* c)
{
@ -1124,6 +1212,42 @@ static void test_resolve_overflows_via_splitting_spaces ()
}
static void test_resolve_overflows_via_splitting_spaces_2 ()
{
size_t buffer_size = 160000;
void* buffer = malloc (buffer_size);
hb_serialize_context_t c (buffer, buffer_size);
populate_serializer_with_split_spaces_2 (&c);
graph_t graph (c.object_graph ());
void* out_buffer = malloc (buffer_size);
hb_serialize_context_t out (out_buffer, buffer_size);
assert (c.offset_overflow ());
hb_resolve_overflows (c.object_graph (), HB_TAG ('G', 'S', 'U', 'B'), &out, 1);
assert (!out.offset_overflow ());
hb_bytes_t result = out.copy_bytes ();
void* expected_buffer = malloc (buffer_size);
hb_serialize_context_t e (expected_buffer, buffer_size);
assert (!e.offset_overflow ());
populate_serializer_with_split_spaces_expected_2 (&e);
hb_bytes_t expected_result = e.copy_bytes ();
assert (result.length == expected_result.length);
for (unsigned i = 0; i < expected_result.length; i++)
{
assert (result[i] == expected_result[i]);
}
result.fini ();
expected_result.fini ();
free (buffer);
free (expected_buffer);
free (out_buffer);
}
// TODO(garretrieger): update will_overflow tests to check the overflows array.
// TODO(garretrieger): add tests for priority raising.
@ -1146,6 +1270,7 @@ main (int argc, char **argv)
test_resolve_overflows_via_isolating_16bit_space ();
test_resolve_overflows_via_isolating_16bit_space_2 ();
test_resolve_overflows_via_splitting_spaces ();
test_resolve_overflows_via_splitting_spaces_2 ();
test_duplicate_leaf ();
test_duplicate_interior ();
}

Loading…
Cancel
Save