Skip to content

Commit a827893

Browse files
committed
Fix double-repossession.
Not completely sure why that can happen just yet, but this should be enough to make it not be a problem.
1 parent 7a24af6 commit a827893

File tree

1 file changed

+38
-32
lines changed

1 file changed

+38
-32
lines changed

src/6model/serialization.c

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,49 +1695,55 @@ static void repossess(PARROT_INTERP, SerializationReader *reader, INTVAL i) {
16951695
PMC *orig_sc = locate_sc(interp, reader, read_int32(table_row, 8));
16961696
PMC *orig_obj = SC_get_object(interp, orig_sc, read_int32(table_row, 12));
16971697

1698-
/* If we have a reposession conflict, make a copy of the original object
1699-
* and reference it from the conflicts list. Push the original (about to
1700-
* be overwritten) object reference too. */
1701-
if (SC_PMC(orig_obj) != orig_sc) {
1702-
PMC *backup = REPR(orig_obj)->allocate(interp, STABLE(orig_obj));
1703-
if (IS_CONCRETE(orig_obj))
1704-
REPR(orig_obj)->copy_to(interp, STABLE(orig_obj), OBJECT_BODY(orig_obj), OBJECT_BODY(backup));
1705-
else
1706-
MARK_AS_TYPE_OBJECT(backup);
1707-
PARROT_GC_WRITE_BARRIER(interp, backup);
1708-
VTABLE_push_pmc(interp, reader->repo_conflicts_list, backup);
1709-
VTABLE_push_pmc(interp, reader->repo_conflicts_list, orig_obj);
1710-
}
1711-
1712-
/* Clear it up, since we'll re-allocate all the bits inside
1713-
* it on deserialization. */
1714-
STABLE(orig_obj)->REPR->gc_free(interp, orig_obj);
1715-
17161698
/* Put it into objects root set at the apporpriate slot. */
17171699
VTABLE_set_pmc_keyed_int(interp, reader->objects_list,
1718-
read_int32(table_row, 4), orig_obj);
1700+
read_int32(table_row, 4), orig_obj);
1701+
1702+
/* Ensure we aren't already trying to repossess the object. */
1703+
if (PMC_data(orig_obj)) {
1704+
/* If we have a reposession conflict, make a copy of the original object
1705+
* and reference it from the conflicts list. Push the original (about to
1706+
* be overwritten) object reference too. */
1707+
if (SC_PMC(orig_obj) != orig_sc) {
1708+
PMC *backup = REPR(orig_obj)->allocate(interp, STABLE(orig_obj));
1709+
if (IS_CONCRETE(orig_obj))
1710+
REPR(orig_obj)->copy_to(interp, STABLE(orig_obj), OBJECT_BODY(orig_obj), OBJECT_BODY(backup));
1711+
else
1712+
MARK_AS_TYPE_OBJECT(backup);
1713+
PARROT_GC_WRITE_BARRIER(interp, backup);
1714+
VTABLE_push_pmc(interp, reader->repo_conflicts_list, backup);
1715+
VTABLE_push_pmc(interp, reader->repo_conflicts_list, orig_obj);
1716+
}
1717+
1718+
/* Clear it up, since we'll re-allocate all the bits inside
1719+
* it on deserialization. */
1720+
STABLE(orig_obj)->REPR->gc_free(interp, orig_obj);
1721+
}
17191722
}
17201723
else if (repo_type == 1) {
17211724
/* Get STable to repossess. */
17221725
PMC *orig_sc = locate_sc(interp, reader, read_int32(table_row, 8));
17231726
PMC *orig_st = SC_get_stable(interp, orig_sc, read_int32(table_row, 12));
17241727

1725-
/* Make sure we don't have a reposession conflict. */
1726-
if (STABLE_STRUCT(orig_st)->sc != orig_sc)
1727-
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
1728-
"STable conflict detected during deserialization.\n"
1729-
"(Probable attempt to load two modules that cannot be loaded together).");
1730-
1731-
/* Clear it up, since we'll re-allocate all the bits inside
1732-
* it on deserialization. */
1733-
if (STABLE_STRUCT(orig_st)->REPR->gc_free_repr_data) {
1734-
STABLE_STRUCT(orig_st)->REPR->gc_free_repr_data(interp, STABLE_STRUCT(orig_st));
1735-
STABLE_STRUCT(orig_st)->REPR_data = NULL;
1736-
}
1737-
17381728
/* Put it into STables root set at the apporpriate slot. */
17391729
VTABLE_set_pmc_keyed_int(interp, reader->stables_list,
17401730
read_int32(table_row, 4), orig_st);
1731+
1732+
/* Ensure we aren't already trying to repossess the STable. */
1733+
if (PMC_data(orig_st)) {
1734+
/* Make sure we don't have a reposession conflict. */
1735+
if (STABLE_STRUCT(orig_st)->sc != orig_sc)
1736+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
1737+
"STable conflict detected during deserialization.\n"
1738+
"(Probable attempt to load two modules that cannot be loaded together).");
1739+
1740+
/* Clear it up, since we'll re-allocate all the bits inside
1741+
* it on deserialization. */
1742+
if (STABLE_STRUCT(orig_st)->REPR->gc_free_repr_data) {
1743+
STABLE_STRUCT(orig_st)->REPR->gc_free_repr_data(interp, STABLE_STRUCT(orig_st));
1744+
STABLE_STRUCT(orig_st)->REPR_data = NULL;
1745+
}
1746+
}
17411747
}
17421748
else {
17431749
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,

0 commit comments

Comments
 (0)