Skip to content
This repository has been archived by the owner on Nov 24, 2022. It is now read-only.

Commit

Permalink
Scavenge & dirty closures
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrea Condoluci committed Mar 4, 2020
1 parent e2571ed commit ac86348
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 13 deletions.
4 changes: 4 additions & 0 deletions asterius/rts/rts.constants.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export const offset_StgLargeBitmap_bitmap = 0x8;
export const sizeof_StgMutArrPtrs = 0x18;
export const offset_StgMutArrPtrs_ptrs = 0x8;
export const offset_StgMutArrPtrs_payload = 0x18;
export const offset_StgMutVar_var = 0x8;
export const offset_StgMVar_head = 0x8;
export const offset_StgMVar_tail = 0x10;
export const offset_StgMVar_value = 0x18;
Expand Down Expand Up @@ -75,6 +76,7 @@ export const offset_StgThunk_payload = 0x10;
export const offset_StgThunkInfoTable_i = 0x0;
export const offset_StgThunkInfoTable_srt = 0x18;
export const offset_StgTSO_id = 0x30;
export const offset_StgTSO_dirty = 0x38;
export const offset_StgTSO_stackobj = 0x18;
export const offset_StgTSO_what_next = 0x20;
export const offset_StgTSO_why_blocked = 0x22;
Expand All @@ -83,6 +85,7 @@ export const offset_StgTSO_ffi_func = 0x480;
export const offset_StgTSO_ffi_return = 0x478;
export const offset_StgTSO_saved_regs = 0x78;
export const offset_StgStack_stack_size = 0x8;
export const offset_StgStack_dirty = 0xc;
export const offset_StgStack_sp = 0x10;
export const offset_StgStack_stack = 0x18;
export const offset_StgUpdateFrame_updatee = 0x8;
Expand All @@ -101,3 +104,4 @@ export const offset_stat_dev = 0x0;
export const offset_stat_ino = 0x8;
export const clock_monotonic = 0x1;
export const clock_realtime = 0x0;
export const MUT_ARR_PTRS_CARD_BITS = 0x7;
107 changes: 95 additions & 12 deletions asterius/rts/rts.gc.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export class GC {
}

/**
* Heap alloactes a physical copy of the given closure.
* Heap allocates a physical copy of the given closure.
* Used during evacuation by {@link GC#evacuateClosure}.
* @param c The source address of the closure
* @param bytes The size in bytes of the closure
Expand Down Expand Up @@ -252,7 +252,7 @@ export class GC {
// a forwarding address: just follow it
return Memory.setDynTag(info, tag);
} else if (this.nonMovedObjects.has(untagged_c)) {
// The closure is eiter pinned or static, and has
// The closure is either pinned or static, and has
// already been enqueued for scavenging: just return it
return c;
} else if (!this.memory.heapAlloced(untagged_c)) {
Expand Down Expand Up @@ -467,6 +467,33 @@ export class GC {
for (let i = 0; i < ptrs; ++i) this.scavengeClosureAt(payload + (i << 3));
}


/**
* Scavenge the pointers of a MUT_ARR, but only
* the areas that are marked as dirty in the
* card table.
* @param p The address of the array payload
* @param ptrs The number of pointers in the array
*/
scavengeMutArrPtrsMarked(p, ptrs) {
// `cards` is the pointer to the card table
const cards = p + (ptrs << 3);
const c = 1 << rtsConstants.MUT_ARR_PTRS_CARD_BITS;
// The length (in bytes) of the card table
const mutArrPtrsCards = ((ptrs + c - 1) >> rtsConstants.MUT_ARR_PTRS_CARD_BITS);
for (let m = 0; m < mutArrPtrsCards; m++) {
if (this.memory.i8Load(cards + m) != 0) {
this.memory.i8Store(cards + m, 0); // clean up
const q = Math.min(p + c, cards);
for (; p < q; p += 8) {
this.scavengeClosureAt(p);
}
} else {
p += c;
}
}
}

scavengeSmallBitmap(payload, bitmap, size) {
for (let i = 0; i < size; ++i)
if (!(Number(bitmap >> BigInt(i)) & 1))
Expand Down Expand Up @@ -736,9 +763,16 @@ export class GC {
this.scavengePointersFirst(c + 8, ptrs);
break;
}
case ClosureTypes.MUT_VAR_CLEAN: {
this.scavengeClosureAt(c + rtsConstants.offset_StgMutVar_var);
break;
}
case ClosureTypes.MUT_VAR_DIRTY: {
this.memory.i64Store(c, this.symbolTable["stg_MUT_VAR_CLEAN_info"]);
this.scavengeClosureAt(c + rtsConstants.offset_StgMutVar_var);
break;
}
case ClosureTypes.BLACKHOLE:
case ClosureTypes.MUT_VAR_CLEAN:
case ClosureTypes.MUT_VAR_DIRTY:
case ClosureTypes.PRIM:
case ClosureTypes.MUT_PRIM:
case ClosureTypes.COMPACT_NFDATA: {
Expand Down Expand Up @@ -814,8 +848,14 @@ export class GC {
this.scavengeClosureAt(c + rtsConstants.offset_StgIndStatic_indirectee);
break;
}
case ClosureTypes.MVAR_CLEAN:
case ClosureTypes.MVAR_CLEAN: {
this.scavengeClosureAt(c + rtsConstants.offset_StgMVar_head);
this.scavengeClosureAt(c + rtsConstants.offset_StgMVar_tail);
this.scavengeClosureAt(c + rtsConstants.offset_StgMVar_value);
break;
}
case ClosureTypes.MVAR_DIRTY: {
this.memory.i64Store(c, this.symbolTable["stg_MVAR_CLEAN_info"]);
this.scavengeClosureAt(c + rtsConstants.offset_StgMVar_head);
this.scavengeClosureAt(c + rtsConstants.offset_StgMVar_tail);
this.scavengeClosureAt(c + rtsConstants.offset_StgMVar_value);
Expand All @@ -825,8 +865,6 @@ export class GC {
break;
}
case ClosureTypes.MUT_ARR_PTRS_CLEAN:
case ClosureTypes.MUT_ARR_PTRS_DIRTY:
case ClosureTypes.MUT_ARR_PTRS_FROZEN_DIRTY:
case ClosureTypes.MUT_ARR_PTRS_FROZEN_CLEAN: {
const ptrs = Number(
this.memory.i64Load(c + rtsConstants.offset_StgMutArrPtrs_ptrs)
Expand All @@ -837,6 +875,28 @@ export class GC {
);
break;
}
case ClosureTypes.MUT_ARR_PTRS_DIRTY: {
this.memory.i64Store(c, this.symbolTable["stg_MUT_ARR_PTRS_CLEAN_info"]);
const ptrs = Number(
this.memory.i64Load(c + rtsConstants.offset_StgMutArrPtrs_ptrs)
);
this.scavengeMutArrPtrsMarked(
c + rtsConstants.offset_StgMutArrPtrs_payload,
ptrs
);
break;
}
case ClosureTypes.MUT_ARR_PTRS_FROZEN_DIRTY: {
this.memory.i64Store(c, this.symbolTable["stg_MUT_ARR_PTRS_FROZEN_CLEAN_info"]);
const ptrs = Number(
this.memory.i64Load(c + rtsConstants.offset_StgMutArrPtrs_ptrs)
);
this.scavengeMutArrPtrsMarked(
c + rtsConstants.offset_StgMutArrPtrs_payload,
ptrs
);
break;
}
case ClosureTypes.WEAK: {
this.scavengeClosureAt(c + rtsConstants.offset_StgWeak_cfinalizers);
this.scavengeClosureAt(c + rtsConstants.offset_StgWeak_key);
Expand All @@ -845,10 +905,12 @@ export class GC {
break;
}
case ClosureTypes.TSO: {
this.memory.i32Store(c + rtsConstants.offset_StgTSO_dirty, 0);
this.scavengeClosureAt(c + rtsConstants.offset_StgTSO_stackobj);
break;
}
case ClosureTypes.STACK: {
this.memory.i32Store(c + rtsConstants.offset_StgStack_dirty, 0);
const stack_size = this.memory.i32Load(
c + rtsConstants.offset_StgStack_stack_size
),
Expand All @@ -858,14 +920,35 @@ export class GC {
break;
}
case ClosureTypes.SMALL_MUT_ARR_PTRS_CLEAN:
case ClosureTypes.SMALL_MUT_ARR_PTRS_DIRTY:
case ClosureTypes.SMALL_MUT_ARR_PTRS_FROZEN_DIRTY:
case ClosureTypes.SMALL_MUT_ARR_PTRS_FROZEN_CLEAN: {
const ptrs = Number(
this.memory.i64Load(c + rtsConstants.offset_StgSmallMutArrPtrs_ptrs)
);
this.scavengePointersFirst(
c + rtsConstants.offset_StgSmallMutArrPtrs_payload,
Number(
this.memory.i64Load(c + rtsConstants.offset_StgSmallMutArrPtrs_ptrs)
)
ptrs
);
break;
}
case ClosureTypes.SMALL_MUT_ARR_PTRS_DIRTY: {
this.memory.i64Store(c, this.symbolTable["stg_SMALL_MUT_ARR_PTRS_CLEAN_info"]);
const ptrs = Number(
this.memory.i64Load(c + rtsConstants.offset_StgSmallMutArrPtrs_ptrs)
);
this.scavengePointersFirst(
c + rtsConstants.offset_StgSmallMutArrPtrs_payload,
ptrs
);
break;
}
case ClosureTypes.SMALL_MUT_ARR_PTRS_FROZEN_DIRTY: {
this.memory.i64Store(c, this.symbolTable["stg_SMALL_MUT_ARR_PTRS_FROZEN_CLEAN_info"]);
const ptrs = Number(
this.memory.i64Load(c + rtsConstants.offset_StgSmallMutArrPtrs_ptrs)
);
this.scavengePointersFirst(
c + rtsConstants.offset_StgSmallMutArrPtrs_payload,
ptrs
);
break;
}
Expand Down
6 changes: 5 additions & 1 deletion asterius/src/Asterius/JSGen/Constants.hs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ rtsConstants =
("sizeof_StgMutArrPtrs", sizeof_StgMutArrPtrs),
("offset_StgMutArrPtrs_ptrs", offset_StgMutArrPtrs_ptrs),
("offset_StgMutArrPtrs_payload", offset_StgMutArrPtrs_payload),
("offset_StgMutVar_var", offset_StgMutVar_var),
("offset_StgMVar_head", offset_StgMVar_head),
("offset_StgMVar_tail", offset_StgMVar_tail),
("offset_StgMVar_value", offset_StgMVar_value),
Expand Down Expand Up @@ -120,6 +121,7 @@ rtsConstants =
("offset_StgThunkInfoTable_i", offset_StgThunkInfoTable_i),
("offset_StgThunkInfoTable_srt", offset_StgThunkInfoTable_srt),
("offset_StgTSO_id", offset_StgTSO_id),
("offset_StgTSO_dirty", offset_StgTSO_dirty),
("offset_StgTSO_stackobj", offset_StgTSO_stackobj),
("offset_StgTSO_what_next", offset_StgTSO_what_next),
("offset_StgTSO_why_blocked", offset_StgTSO_why_blocked),
Expand All @@ -128,6 +130,7 @@ rtsConstants =
("offset_StgTSO_ffi_return", offset_StgTSO_ffi_return),
("offset_StgTSO_saved_regs", offset_StgTSO_saved_regs),
("offset_StgStack_stack_size", offset_StgStack_stack_size),
("offset_StgStack_dirty", offset_StgStack_dirty),
("offset_StgStack_sp", offset_StgStack_sp),
("offset_StgStack_stack", offset_StgStack_stack),
("offset_StgUpdateFrame_updatee", offset_StgUpdateFrame_updatee),
Expand All @@ -145,6 +148,7 @@ rtsConstants =
("offset_stat_dev", offset_stat_dev),
("offset_stat_ino", offset_stat_ino),
("clock_monotonic", clock_monotonic),
("clock_realtime", clock_realtime)
("clock_realtime", clock_realtime),
("MUT_ARR_PTRS_CARD_BITS", _MUT_ARR_PTRS_CARD_BITS)
]
]
6 changes: 6 additions & 0 deletions asterius/src/Asterius/Ld.hs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ rtsUsedSymbols =
"stg_BLACKHOLE_info",
"stg_WHITEHOLE_info",
"stg_IND_info",
"stg_MVAR_CLEAN_info",
"stg_MUT_ARR_CLEAN_info",
"stg_MUT_ARR_PTRS_FROZEN_CLEAN_info",
"stg_MUT_VAR_CLEAN_info",
"stg_SMALL_MUT_ARR_PTRS_CLEAN_info",
"stg_SMALL_MUT_ARR_PTRS_FROZEN_CLEAN_info",
"stg_DEAD_WEAK_info",
"stg_marked_upd_frame_info",
"stg_NO_FINALIZER_closure",
Expand Down
4 changes: 4 additions & 0 deletions ghc-toolkit/cbits/ghc_constants.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ HsInt offset_StgMutArrPtrs_payload() {
return offsetof(StgMutArrPtrs, payload);
}

HsInt offset_StgMutVar_var() { return offsetof(StgMutVar, var); }

HsInt offset_StgMVar_head() { return offsetof(StgMVar, head); }

HsInt offset_StgMVar_tail() { return offsetof(StgMVar, tail); }
Expand Down Expand Up @@ -527,3 +529,5 @@ HsInt offset_StgStableName_sn() { return offsetof(StgStableName, sn); }
HsInt clock_monotonic() { return CLOCK_MONOTONIC; }

HsInt clock_realtime() { return CLOCK_REALTIME; }

HsInt _MUT_ARR_PTRS_CARD_BITS() { return MUT_ARR_PTRS_CARD_BITS; }
4 changes: 4 additions & 0 deletions ghc-toolkit/src/Language/Haskell/GHC/Toolkit/Constants.hs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ foreign import ccall unsafe "offset_StgMutArrPtrs_size"
foreign import ccall unsafe "offset_StgMutArrPtrs_payload"
offset_StgMutArrPtrs_payload :: Int

foreign import ccall unsafe "offset_StgMutVar_var" offset_StgMutVar_var :: Int

foreign import ccall unsafe "offset_StgMVar_head" offset_StgMVar_head :: Int

foreign import ccall unsafe "offset_StgMVar_tail" offset_StgMVar_tail :: Int
Expand Down Expand Up @@ -587,3 +589,5 @@ foreign import ccall unsafe "offset_StgStableName_sn"
foreign import ccall unsafe "clock_monotonic" clock_monotonic :: Int

foreign import ccall unsafe "clock_realtime" clock_realtime :: Int

foreign import ccall unsafe "_MUT_ARR_PTRS_CARD_BITS" _MUT_ARR_PTRS_CARD_BITS :: Int

0 comments on commit ac86348

Please sign in to comment.