aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorRichard Brooksby2012-09-12 13:22:10 +0100
committerRichard Brooksby2012-09-12 13:22:10 +0100
commitce7ddee9f71ac930a28edb23f536a38fcf21761d (patch)
treeecdea2911d2562379c6c54b4939d52d26c8d54fb /mps/code
parenta9bcf5293bf963cdd4e3fa159c12bbaf957e5fc2 (diff)
parent086ecb5e4fac8ac05d8196d2ad1648b9effa261f (diff)
downloademacs-ce7ddee9f71ac930a28edb23f536a38fcf21761d.tar.gz
emacs-ce7ddee9f71ac930a28edb23f536a38fcf21761d.zip
Merging recent changes from masters, including awl fix to unstick open dylan bootstrap.
Copied from Perforce Change: 179440 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/commpre.nmk4
-rw-r--r--mps/code/config.h8
-rw-r--r--mps/code/eventdef.h14
-rw-r--r--mps/code/poolawl.c83
4 files changed, 78 insertions, 31 deletions
diff --git a/mps/code/commpre.nmk b/mps/code/commpre.nmk
index b510c9779e1..0afcab6fe96 100644
--- a/mps/code/commpre.nmk
+++ b/mps/code/commpre.nmk
@@ -117,7 +117,7 @@ CFLAGSEXTERNAL =
117# %%VARIETY: When adding a new variety, define a macro containing the set 117# %%VARIETY: When adding a new variety, define a macro containing the set
118# of flags for the new variety. 118# of flags for the new variety.
119CFRASH = /DCONFIG_VAR_RASH $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSEXTERNAL) 119CFRASH = /DCONFIG_VAR_RASH $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSEXTERNAL)
120CFHOT = /DCONFIG_VAR_HOT $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSEXTERNAL) 120CFHOT = /DCONFIG_VAR_HOT $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSINTERNAL)
121CFDIAG = /DCONFIG_VAR_DIAG $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSINTERNAL) 121CFDIAG = /DCONFIG_VAR_DIAG $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSINTERNAL)
122CFCOOL = /DCONFIG_VAR_COOL $(CRTFLAGSCOOL) $(CFLAGSCOOL) $(CFLAGSINTERNAL) 122CFCOOL = /DCONFIG_VAR_COOL $(CRTFLAGSCOOL) $(CFLAGSCOOL) $(CFLAGSINTERNAL)
123 123
@@ -134,7 +134,7 @@ LINKFLAGSINTERNAL = /DEBUG
134LINKFLAGSEXTERNAL = /RELEASE 134LINKFLAGSEXTERNAL = /RELEASE
135 135
136LFRASH = $(LINKFLAGSHOT) $(LINKFLAGSEXTERNAL) 136LFRASH = $(LINKFLAGSHOT) $(LINKFLAGSEXTERNAL)
137LFHOT = $(LINKFLAGSHOT) $(LINKFLAGSEXTERNAL) 137LFHOT = $(LINKFLAGSHOT) $(LINKFLAGSINTERNAL)
138LFDIAG = $(LINKFLAGSHOT) $(LINKFLAGSINTERNAL) 138LFDIAG = $(LINKFLAGSHOT) $(LINKFLAGSINTERNAL)
139LFCOOL = $(LINKFLAGSCOOL) $(LINKFLAGSINTERNAL) 139LFCOOL = $(LINKFLAGSCOOL) $(LINKFLAGSINTERNAL)
140 140
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: