aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorRichard Brooksby2012-09-11 21:21:26 +0100
committerRichard Brooksby2012-09-11 21:21:26 +0100
commit789066596d1b4f74706620fe6b60d1927a21723e (patch)
tree8003a0f656bc9e9f9d1ba21031fee24f63b6bda9 /mps/code
parent346ab4aa0943646ae69758a89ece3dc21a8f5524 (diff)
downloademacs-789066596d1b4f74706620fe6b60d1927a21723e.tar.gz
emacs-789066596d1b4f74706620fe6b60d1927a21723e.zip
Configuring awl pool to give give up and scan an entire segment after 200 single access hits, after observing open dylan bootstrap on ubuntu 12 hammering the table and making no progress.
AWL pool no longer tries a single access if the trace band has reached rank WEAK, since it doesn't need to. Copied from Perforce Change: 179434 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/config.h8
-rw-r--r--mps/code/eventdef.h14
-rw-r--r--mps/code/poolawl.c83
3 files changed, 76 insertions, 29 deletions
diff --git a/mps/code/config.h b/mps/code/config.h
index 8df33201f5f..5eb8ee50e13 100644
--- a/mps/code/config.h
+++ b/mps/code/config.h
@@ -393,6 +393,14 @@
393#define AMCLargeSegPAGES ((Count)8) 393#define AMCLargeSegPAGES ((Count)8)
394 394
395 395
396/* Pool Class AWL configuration -- see poolawl.c for usage */
397
398#define AWL_HAVE_SEG_SA_LIMIT TRUE
399#define AWL_SEG_SA_LIMIT 200 /* TODO: Improve guesswork with measurements */
400#define AWL_HAVE_TOTAL_SA_LIMIT FALSE
401#define AWL_TOTAL_SA_LIMIT 0
402
403
396#endif /* config_h */ 404#endif /* config_h */
397 405
398 406
diff --git a/mps/code/eventdef.h b/mps/code/eventdef.h
index 56d0271975b..9f5ea780787 100644
--- a/mps/code/eventdef.h
+++ b/mps/code/eventdef.h
@@ -68,7 +68,7 @@
68 */ 68 */
69 69
70#define EventNameMAX ((size_t)19) 70#define EventNameMAX ((size_t)19)
71#define EventCodeMAX ((EventCode)0x0071) 71#define EventCodeMAX ((EventCode)0x0073)
72 72
73#define EVENT_LIST(EVENT, X) \ 73#define EVENT_LIST(EVENT, X) \
74 /* 0123456789012345678 <- don't exceed without changing EventNameMAX */ \ 74 /* 0123456789012345678 <- don't exceed without changing EventNameMAX */ \
@@ -177,7 +177,9 @@
177 EVENT(X, MessagesExist , 0x006E, TRUE, Arena) \ 177 EVENT(X, MessagesExist , 0x006E, TRUE, Arena) \
178 EVENT(X, ChainCondemnAuto , 0x006F, TRUE, Trace) \ 178 EVENT(X, ChainCondemnAuto , 0x006F, TRUE, Trace) \
179 EVENT(X, TraceFindGrey , 0x0070, TRUE, Trace) \ 179 EVENT(X, TraceFindGrey , 0x0070, TRUE, Trace) \
180 EVENT(X, TraceBandAdvance , 0x0071, TRUE, Trace) 180 EVENT(X, TraceBandAdvance , 0x0071, TRUE, Trace) \
181 EVENT(X, AWLDeclineTotal , 0x0072, TRUE, Trace) \
182 EVENT(X, AWLDeclineSeg , 0x0073, TRUE, Trace)
181 183
182 184
183/* Remember to update EventNameMAX and EventCodeMAX in eventcom.h! 185/* Remember to update EventNameMAX and EventCodeMAX in eventcom.h!
@@ -610,6 +612,14 @@
610 PARAM(X, 1, W, ti) \ 612 PARAM(X, 1, W, ti) \
611 PARAM(X, 2, W, rank) 613 PARAM(X, 2, W, rank)
612 614
615#define EVENT_AWLDeclineTotal_PARAMS(PARAM, X) \
616 PARAM(X, 0, P, seg) /* segment declined single access */ \
617 PARAM(X, 1, U, succAccesses) /* total successive accesses */
618
619#define EVENT_AWLDeclineSeg_PARAMS(PARAM, X) \
620 PARAM(X, 0, P, seg) /* segment declined single access */ \
621 PARAM(X, 1, U, singleAccesses) /* single accesses this cycle */
622
613 623
614#endif /* eventdef_h */ 624#endif /* eventdef_h */
615 625
diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c
index da63a4374d3..e775517a7b2 100644
--- a/mps/code/poolawl.c
+++ b/mps/code/poolawl.c
@@ -289,50 +289,79 @@ DEFINE_SEG_CLASS(AWLSegClass, class)
289} 289}
290 290
291 291
292/* Single access permission control parameters */ 292/* Single access pattern control parameters
293 *
294 * These control the number of expensive emulated single-accesses we allow
295 * before we give up and scan a segment at whatever rank, possibly causing
296 * retention of weak objects.
297 *
298 * AWLSegSALimit is the number of accesses for a single segment in a GC cycle.
299 * AWLTotalSALimit is the total number of accesses during a GC cycle.
300 *
301 * These should be set in config.h, but are here in static variables so that
302 * it's possible to tweak them in a debugger.
303 */
293 304
294Count AWLSegSALimit = 0; /* Number of single accesses permitted per segment */ 305Count AWLSegSALimit = AWL_SEG_SA_LIMIT;
295Bool AWLHaveSegSALimit = FALSE; /* When TRUE, AWLSegSALimit applies */ 306Bool AWLHaveSegSALimit = AWL_HAVE_SEG_SA_LIMIT;
296 307
297Count AWLTotalSALimit = 0; /* Number of single accesses permitted in a row */ 308Count AWLTotalSALimit = AWL_TOTAL_SA_LIMIT;
298Bool AWLHaveTotalSALimit = FALSE; /* When TRUE, AWLTotalSALimit applies */ 309Bool AWLHaveTotalSALimit = AWL_HAVE_TOTAL_SA_LIMIT;
299 310
300 311
301/* Determine whether to permit scanning a single ref. */ 312/* Determine whether to permit scanning a single ref. */
302 313
303static Bool AWLCanTrySingleAccess(AWL awl, Seg seg, Addr addr) 314static Bool AWLCanTrySingleAccess(Arena arena, AWL awl, Seg seg, Addr addr)
304{ 315{
316 AWLSeg awlseg;
317
305 AVERT(AWL, awl); 318 AVERT(AWL, awl);
306 AVERT(Seg, seg); 319 AVERT(Seg, seg);
307 AVER(addr != NULL); 320 AVER(addr != NULL);
308 321
309 /* .assume.noweak */ 322 /* .assume.noweak */
310 /* .assume.alltraceable */ 323 /* .assume.alltraceable */
311 if(RankSetIsMember(SegRankSet(seg), RankWEAK)) { 324 if (!RankSetIsMember(SegRankSet(seg), RankWEAK))
312 AWLSeg awlseg; 325 return FALSE;
313 326
314 awlseg = Seg2AWLSeg(seg); 327 /* If there are no traces in progress then the segment isn't read
315 AVERT(AWLSeg, awlseg); 328 protected and this is just an ordinary write barrier hit. No need to
329 scan at all. */
330 if (arena->flippedTraces == TraceSetEMPTY) {
331 AVER(!(SegSM(seg) & AccessREAD));
332 return FALSE;
333 }
316 334
317 if(AWLHaveTotalSALimit) { 335 /* The trace is already in the weak band, so we can scan the whole
318 if(AWLTotalSALimit < awl->succAccesses) { 336 segment without retention anyway. Go for it. */
319 STATISTIC(awl->stats.declined++); 337 if (TraceRankForAccess(arena, seg) == RankWEAK)
320 return FALSE; /* decline single access because of total limit */ 338 return FALSE;
321 }
322 }
323 339
324 if(AWLHaveSegSALimit) { 340 awlseg = Seg2AWLSeg(seg);
325 if(AWLSegSALimit < awlseg->singleAccesses) { 341 AVERT(AWLSeg, awlseg);
326 STATISTIC(awl->stats.declined++);
327 return FALSE; /* decline single access because of segment limit */
328 }
329 }
330 342
331 return TRUE; 343 /* If there have been too many single accesses in a row then don't
344 keep trying them, even if it means retaining objects. */
345 if(AWLHaveTotalSALimit) {
346 if(awl->succAccesses >= AWLTotalSALimit) {
347 STATISTIC(awl->stats.declined++);
348 EVENT2(AWLDeclineTotal, seg, awl->succAccesses);
349 return FALSE; /* decline single access because of total limit */
350 }
351 }
332 352
333 } else { 353 /* If there have been too many single accesses to this segment
334 return FALSE; /* Single access only for weak segs (.assume.noweak) */ 354 then don't keep trying them, even if it means retaining objects.
355 (Observed behaviour in Open Dylan 2012-09-10 by RB.) */
356 if(AWLHaveSegSALimit) {
357 if(awlseg->singleAccesses >= AWLSegSALimit) {
358 STATISTIC(awl->stats.declined++);
359 EVENT2(AWLDeclineSeg, seg, awlseg->singleAccesses);
360 return FALSE; /* decline single access because of segment limit */
361 }
335 } 362 }
363
364 return TRUE;
336} 365}
337 366
338 367
@@ -1116,9 +1145,9 @@ static Res AWLAccess(Pool pool, Seg seg, Addr addr,
1116 AVER(SegBase(seg) <= addr); 1145 AVER(SegBase(seg) <= addr);
1117 AVER(addr < SegLimit(seg)); 1146 AVER(addr < SegLimit(seg));
1118 AVER(SegPool(seg) == pool); 1147 AVER(SegPool(seg) == pool);
1119 1148
1120 /* Attempt scanning a single reference if permitted */ 1149 /* Attempt scanning a single reference if permitted */
1121 if(AWLCanTrySingleAccess(awl, seg, addr)) { 1150 if(AWLCanTrySingleAccess(PoolArena(pool), awl, seg, addr)) {
1122 res = PoolSingleAccess(pool, seg, addr, mode, context); 1151 res = PoolSingleAccess(pool, seg, addr, mode, context);
1123 switch(res) { 1152 switch(res) {
1124 case ResOK: 1153 case ResOK: