Skip to content

Commit dc4a077

Browse files
committed
Always clear the source location when moving locations.
1 parent 7663fb8 commit dc4a077

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

truffle/src/com.oracle.truffle.api.object/src/com/oracle/truffle/api/object/DynamicObjectLibraryImpl.java

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,8 @@ static RemovePlan prepareRemove(Shape shapeBefore, Shape shapeAfter, Property re
393393
if (canMoveInPlace) {
394394
if (moves.isEmpty()) {
395395
Location removedPropertyLoc = removedProperty.getLocation();
396-
if (!removedPropertyLoc.isPrimitive()) {
397-
// Use a no-op move to clear the location of the removed property.
398-
moves.add(new Move(removedPropertyLoc, removedPropertyLoc, 0, 0));
399-
}
396+
// Use a no-op move to clear the location of the removed property.
397+
moves.add(new Move(removedPropertyLoc, removedPropertyLoc, 0, 0));
400398
} else if (!isSorted(moves)) {
401399
moves.sort(Move::compareTo);
402400
}
@@ -415,6 +413,10 @@ private static boolean isSorted(List<Move> moves) {
415413
return true;
416414
}
417415

416+
/**
417+
* Moves the value from one location to another, and clears the from location. If both locations
418+
* are the same, only clears the location.
419+
*/
418420
private static final class Move implements Comparable<Move> {
419421
private final Location fromLoc;
420422
private final Location toLoc;
@@ -432,10 +434,10 @@ private static final class Move implements Comparable<Move> {
432434
}
433435

434436
void perform(DynamicObject obj) {
435-
if (fromLoc == toLoc) {
436-
return;
437+
if (fromLoc != toLoc) {
438+
performSet(obj, performGet(obj));
437439
}
438-
performSet(obj, performGet(obj));
440+
clear(obj);
439441
}
440442

441443
Object performGet(DynamicObject obj) {
@@ -446,8 +448,14 @@ void performSet(DynamicObject obj, Object value) {
446448
toLoc.setSafe(obj, value, false, true);
447449
}
448450

449-
void clear(DynamicObject obj) {
450-
// clear location to avoid memory leak
451+
Object performGetAndClear(DynamicObject obj) {
452+
Object value = performGet(obj);
453+
clear(obj);
454+
return value;
455+
}
456+
457+
private void clear(DynamicObject obj) {
458+
// clear the location to avoid memory leak AND kill the location identity
451459
fromLoc.clear(obj);
452460
}
453461

@@ -498,25 +506,19 @@ void perform(DynamicObject object) {
498506
moves[i].perform(object);
499507
}
500508

501-
if (moves.length > 0) {
502-
moves[0].clear(object);
503-
}
504-
505509
DynamicObjectSupport.trimToSize(object, shapeBefore, shapeAfter);
506-
object.setShape(shapeAfter);
507510
} else {
508511
// we cannot perform the moves in place, so stash away the values
509512
Object[] tempValues = new Object[moves.length];
510513
for (int i = moves.length - 1; i >= 0; i--) {
511-
tempValues[i] = moves[i].performGet(object);
512-
moves[i].clear(object);
514+
tempValues[i] = moves[i].performGetAndClear(object);
513515
}
514516
DynamicObjectSupport.resize(object, shapeBefore, shapeAfter);
515517
for (int i = moves.length - 1; i >= 0; i--) {
516518
moves[i].performSet(object, tempValues[i]);
517519
}
518-
object.setShape(shapeAfter);
519520
}
521+
object.setShape(shapeAfter);
520522
}
521523

522524
@TruffleBoundary

0 commit comments

Comments
 (0)