Skip to content

Commit

Permalink
Have a per-run time budget for import suggestions
Browse files Browse the repository at this point in the history
Keep a budget of import suggestions per run. The first timeout is 10sec.
Each successive timeout is the previous timeout reduced by the search time
of the previous suggestion search, but at least half the previous timeout.
  • Loading branch information
odersky committed Jun 11, 2020
1 parent 3dfba6d commit 1cb4279
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 5 deletions.
17 changes: 17 additions & 0 deletions compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,23 @@ trait ImplicitRunInfo:

private val EmptyTermRefSet = new TermRefSet(using NoContext)

/** Global timeout to stop looking for further implicit suggestions, in ms.
* This is for the first import suggestion; subsequent suggestions
* get smaller timeouts.
*/
private inline val suggestFirstImplicitsTimeOut = 10000

private var importSuggestionBudget: Long = suggestFirstImplicitsTimeOut

/** The current timeout for import suggestions */
def nextImportSuggestionTimeout() = importSuggestionBudget

/** Reduce the import suggestion timeout by `ms`, but make sure that
* the new timeout is at least half the old one.
*/
def reduceImportSuggestionTimeout(ms: Long) =
importSuggestionBudget = (importSuggestionBudget - ms) max (importSuggestionBudget / 2)

private def isExcluded(sym: Symbol) =
if migrateTo3 then false else sym.is(Package) || sym.isPackageObject

Expand Down
13 changes: 8 additions & 5 deletions compiler/src/dotty/tools/dotc/typer/ImportSuggestions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ trait ImportSuggestions:
/** Timeout to test a single implicit value as a suggestion, in ms */
private inline val testOneImplicitTimeOut = 500

/** Global timeout to stop looking for further implicit suggestions, in ms */
private inline val suggestImplicitTimeOut = 10000

/** A list of TermRefs referring to the roots where suggestions for
* imports of givens or extension methods that might fix a type error
* are searched.
Expand Down Expand Up @@ -145,7 +142,11 @@ trait ImportSuggestions:
*/
private def importSuggestions(pt: Type)(using Context): (List[TermRef], List[TermRef]) =
val timer = new Timer()
val deadLine = System.currentTimeMillis() + suggestImplicitTimeOut
val allotted = ctx.run.nextImportSuggestionTimeout()
if allotted <= 1 then return (Nil, Nil)
implicits.println(i"looking for import suggestions, timeout = ${allotted}ms")
val start = System.currentTimeMillis()
val deadLine = start + allotted

// Candidates that are already available without explicit import because they
// are already provided by the context (imported or inherited) or because they
Expand Down Expand Up @@ -249,7 +250,9 @@ trait ImportSuggestions:
println("caught exception when searching for suggestions")
ex.printStackTrace()
(Nil, Nil)
finally timer.cancel()
finally
timer.cancel()
ctx.run.reduceImportSuggestionTimeout(System.currentTimeMillis() - start)
end importSuggestions

/** The `ref` parts of this list of pairs, discarding subsequent elements that
Expand Down
Loading

0 comments on commit 1cb4279

Please sign in to comment.