diff options
| author | Richard Brooksby | 2012-09-12 13:22:10 +0100 |
|---|---|---|
| committer | Richard Brooksby | 2012-09-12 13:22:10 +0100 |
| commit | ce7ddee9f71ac930a28edb23f536a38fcf21761d (patch) | |
| tree | ecdea2911d2562379c6c54b4939d52d26c8d54fb /mps/code | |
| parent | a9bcf5293bf963cdd4e3fa159c12bbaf957e5fc2 (diff) | |
| parent | 086ecb5e4fac8ac05d8196d2ad1648b9effa261f (diff) | |
| download | emacs-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.nmk | 4 | ||||
| -rw-r--r-- | mps/code/config.h | 8 | ||||
| -rw-r--r-- | mps/code/eventdef.h | 14 | ||||
| -rw-r--r-- | mps/code/poolawl.c | 83 |
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. |
| 119 | CFRASH = /DCONFIG_VAR_RASH $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSEXTERNAL) | 119 | CFRASH = /DCONFIG_VAR_RASH $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSEXTERNAL) |
| 120 | CFHOT = /DCONFIG_VAR_HOT $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSEXTERNAL) | 120 | CFHOT = /DCONFIG_VAR_HOT $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSINTERNAL) |
| 121 | CFDIAG = /DCONFIG_VAR_DIAG $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSINTERNAL) | 121 | CFDIAG = /DCONFIG_VAR_DIAG $(CRTFLAGSHOT) $(CFLAGSHOT) $(CFLAGSINTERNAL) |
| 122 | CFCOOL = /DCONFIG_VAR_COOL $(CRTFLAGSCOOL) $(CFLAGSCOOL) $(CFLAGSINTERNAL) | 122 | CFCOOL = /DCONFIG_VAR_COOL $(CRTFLAGSCOOL) $(CFLAGSCOOL) $(CFLAGSINTERNAL) |
| 123 | 123 | ||
| @@ -134,7 +134,7 @@ LINKFLAGSINTERNAL = /DEBUG | |||
| 134 | LINKFLAGSEXTERNAL = /RELEASE | 134 | LINKFLAGSEXTERNAL = /RELEASE |
| 135 | 135 | ||
| 136 | LFRASH = $(LINKFLAGSHOT) $(LINKFLAGSEXTERNAL) | 136 | LFRASH = $(LINKFLAGSHOT) $(LINKFLAGSEXTERNAL) |
| 137 | LFHOT = $(LINKFLAGSHOT) $(LINKFLAGSEXTERNAL) | 137 | LFHOT = $(LINKFLAGSHOT) $(LINKFLAGSINTERNAL) |
| 138 | LFDIAG = $(LINKFLAGSHOT) $(LINKFLAGSINTERNAL) | 138 | LFDIAG = $(LINKFLAGSHOT) $(LINKFLAGSINTERNAL) |
| 139 | LFCOOL = $(LINKFLAGSCOOL) $(LINKFLAGSINTERNAL) | 139 | LFCOOL = $(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 | ||
| 294 | Count AWLSegSALimit = 0; /* Number of single accesses permitted per segment */ | 305 | Count AWLSegSALimit = AWL_SEG_SA_LIMIT; |
| 295 | Bool AWLHaveSegSALimit = FALSE; /* When TRUE, AWLSegSALimit applies */ | 306 | Bool AWLHaveSegSALimit = AWL_HAVE_SEG_SA_LIMIT; |
| 296 | 307 | ||
| 297 | Count AWLTotalSALimit = 0; /* Number of single accesses permitted in a row */ | 308 | Count AWLTotalSALimit = AWL_TOTAL_SA_LIMIT; |
| 298 | Bool AWLHaveTotalSALimit = FALSE; /* When TRUE, AWLTotalSALimit applies */ | 309 | Bool 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 | ||
| 303 | static Bool AWLCanTrySingleAccess(AWL awl, Seg seg, Addr addr) | 314 | static 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: |