Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix double-repossession.

Not completely sure why that can happen just yet, but this should be
enough to make it not be a problem.
  • Loading branch information...
commit a827893c9e2925b1f2eb9514b222fb989aaf71e8 1 parent 7a24af6
@jnthn jnthn authored
Showing with 38 additions and 32 deletions.
  1. +38 −32 src/6model/serialization.c
View
70 src/6model/serialization.c
@@ -1695,49 +1695,55 @@ static void repossess(PARROT_INTERP, SerializationReader *reader, INTVAL i) {
PMC *orig_sc = locate_sc(interp, reader, read_int32(table_row, 8));
PMC *orig_obj = SC_get_object(interp, orig_sc, read_int32(table_row, 12));
- /* If we have a reposession conflict, make a copy of the original object
- * and reference it from the conflicts list. Push the original (about to
- * be overwritten) object reference too. */
- if (SC_PMC(orig_obj) != orig_sc) {
- PMC *backup = REPR(orig_obj)->allocate(interp, STABLE(orig_obj));
- if (IS_CONCRETE(orig_obj))
- REPR(orig_obj)->copy_to(interp, STABLE(orig_obj), OBJECT_BODY(orig_obj), OBJECT_BODY(backup));
- else
- MARK_AS_TYPE_OBJECT(backup);
- PARROT_GC_WRITE_BARRIER(interp, backup);
- VTABLE_push_pmc(interp, reader->repo_conflicts_list, backup);
- VTABLE_push_pmc(interp, reader->repo_conflicts_list, orig_obj);
- }
-
- /* Clear it up, since we'll re-allocate all the bits inside
- * it on deserialization. */
- STABLE(orig_obj)->REPR->gc_free(interp, orig_obj);
-
/* Put it into objects root set at the apporpriate slot. */
VTABLE_set_pmc_keyed_int(interp, reader->objects_list,
- read_int32(table_row, 4), orig_obj);
+ read_int32(table_row, 4), orig_obj);
+
+ /* Ensure we aren't already trying to repossess the object. */
+ if (PMC_data(orig_obj)) {
+ /* If we have a reposession conflict, make a copy of the original object
+ * and reference it from the conflicts list. Push the original (about to
+ * be overwritten) object reference too. */
+ if (SC_PMC(orig_obj) != orig_sc) {
+ PMC *backup = REPR(orig_obj)->allocate(interp, STABLE(orig_obj));
+ if (IS_CONCRETE(orig_obj))
+ REPR(orig_obj)->copy_to(interp, STABLE(orig_obj), OBJECT_BODY(orig_obj), OBJECT_BODY(backup));
+ else
+ MARK_AS_TYPE_OBJECT(backup);
+ PARROT_GC_WRITE_BARRIER(interp, backup);
+ VTABLE_push_pmc(interp, reader->repo_conflicts_list, backup);
+ VTABLE_push_pmc(interp, reader->repo_conflicts_list, orig_obj);
+ }
+
+ /* Clear it up, since we'll re-allocate all the bits inside
+ * it on deserialization. */
+ STABLE(orig_obj)->REPR->gc_free(interp, orig_obj);
+ }
}
else if (repo_type == 1) {
/* Get STable to repossess. */
PMC *orig_sc = locate_sc(interp, reader, read_int32(table_row, 8));
PMC *orig_st = SC_get_stable(interp, orig_sc, read_int32(table_row, 12));
- /* Make sure we don't have a reposession conflict. */
- if (STABLE_STRUCT(orig_st)->sc != orig_sc)
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "STable conflict detected during deserialization.\n"
- "(Probable attempt to load two modules that cannot be loaded together).");
-
- /* Clear it up, since we'll re-allocate all the bits inside
- * it on deserialization. */
- if (STABLE_STRUCT(orig_st)->REPR->gc_free_repr_data) {
- STABLE_STRUCT(orig_st)->REPR->gc_free_repr_data(interp, STABLE_STRUCT(orig_st));
- STABLE_STRUCT(orig_st)->REPR_data = NULL;
- }
-
/* Put it into STables root set at the apporpriate slot. */
VTABLE_set_pmc_keyed_int(interp, reader->stables_list,
read_int32(table_row, 4), orig_st);
+
+ /* Ensure we aren't already trying to repossess the STable. */
+ if (PMC_data(orig_st)) {
+ /* Make sure we don't have a reposession conflict. */
+ if (STABLE_STRUCT(orig_st)->sc != orig_sc)
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "STable conflict detected during deserialization.\n"
+ "(Probable attempt to load two modules that cannot be loaded together).");
+
+ /* Clear it up, since we'll re-allocate all the bits inside
+ * it on deserialization. */
+ if (STABLE_STRUCT(orig_st)->REPR->gc_free_repr_data) {
+ STABLE_STRUCT(orig_st)->REPR->gc_free_repr_data(interp, STABLE_STRUCT(orig_st));
+ STABLE_STRUCT(orig_st)->REPR_data = NULL;
+ }
+ }
}
else {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
Please sign in to comment.
Something went wrong with that request. Please try again.