Browse Source

Fix recursive maxlinktime calls (#33)

* Fix: Avoid recursive calling of MaxLinkTime() by adding a maxlinktime-cache

When having a project with many imported files which import each other too this leads to an exorbitant call to MaxLinkTime() as it calls it again and again for all used files (even if already calculated before). In my game "TVTower" this lead to 2456886754 (!) calls while the cache one only needs 886 and 1419 cache calls.

Compilation ("STAGE_LINK") time is reduced from ~157s to ~0.6s.

* Invalidate maxLinkTimeCache when build of file is required.
Ronny Otto 7 years ago
parent
commit
5023fc0e43
2 changed files with 51 additions and 35 deletions
  1. 12 12
      bmk_make.bmx
  2. 39 23
      bmk_modutil.bmx

+ 12 - 12
bmk_make.bmx

@@ -342,7 +342,7 @@ Type TBuildManager
 		
 		source.bcc_opts = bcc_opts
 
-		source.requiresBuild = opt_all
+		source.SetRequiresBuild(opt_all)
 
 		CalculateDependencies(source, False, opt_all)
 
@@ -414,7 +414,7 @@ Type TBuildManager
 						
 							If m.requiresBuild Or (m.time > m.obj_time Or m.iface_time < m.MaxIfaceTime()) Then
 							
-								m.requiresBuild = True
+								m.SetRequiresBuild(True)
 
 								If Not opt_quiet Then
 									Print ShowPct(m.pct) + "Processing:" + StripDir(m.path)
@@ -436,14 +436,14 @@ Type TBuildManager
 
 							For Local s:TSourceFile = EachIn m.depsList
 								If s.requiresBuild Then
-									m.requiresBuild = True
+									m.SetRequiresBuild(True)
 									Exit
 								End If
 							Next
 
 							If m.requiresBuild Or (m.time > m.obj_time Or m.iface_time < m.MaxIfaceTime()) Then
 							
-								m.requiresBuild = True
+								m.SetRequiresBuild(True)
 
 								If Not opt_quiet Then
 									Print ShowPct(m.pct) + "Converting:" + StripDir(StripExt(m.obj_path) + ".s")
@@ -459,7 +459,7 @@ Type TBuildManager
 
 							If m.requiresBuild Or (m.time > m.obj_time Or m.iface_time < m.MaxIfaceTime()) Then
 							
-								m.requiresBuild = True
+								m.SetRequiresBuild(True)
 								
 								If processor.BCCVersion() <> "BlitzMax" Then
 
@@ -565,7 +565,7 @@ Type TBuildManager
 				Else If Match(m.ext, "s") Then
 
 					If m.time > m.obj_time Then ' object is older or doesn't exist
-						m.requiresBuild = True
+						m.SetRequiresBuild(True)
 					End If
 
 					If m.requiresBuild Then
@@ -587,7 +587,7 @@ Type TBuildManager
 					If Not m.dontbuild Then
 						' c/c++ source
 						If m.time > m.obj_time Then ' object is older or doesn't exist
-							m.requiresBuild = True
+							m.SetRequiresBuild(True)
 						End If
 						
 						If m.requiresBuild Then
@@ -707,7 +707,7 @@ Type TBuildManager
 					If s Then
 	
 						If rebuildImports Then
-							s.requiresBuild = rebuildImports
+							s.SetRequiresBuild(rebuildImports)
 						End If
 	
 						If Match(s.ext, "bmx") Then
@@ -739,11 +739,11 @@ Type TBuildManager
 							' if file that we generate is missing, we need to rebuild
 							If processor.BCCVersion() = "BlitzMax" Then
 								If Not FileType(StripExt(s.obj_path) + ".s") Then
-									s.requiresBuild = True
+									s.SetRequiresBuild(True)
 								End If
 							Else
 								If Not FileType(StripExt(s.obj_path) + ".c") Then
-									s.requiresBuild = True
+									s.SetRequiresBuild(True)
 								End If
 							End If
 							
@@ -1051,11 +1051,11 @@ Type TBuildManager
 	
 			source.bcc_opts = bcc_opts
 			
-			source.requiresBuild = rebuild
+			source.SetRequiresBuild(rebuild)
 
 			' interface is REQUIRED for compilation
 			If Not iface_time Then
-				source.requiresBuild = True
+				source.SetRequiresBuild(True)
 			End If
 
 			If m <> "brl.blitz" Then	

+ 39 - 23
bmk_modutil.bmx

@@ -74,6 +74,8 @@ Type TSourceFile
 	Field optsCache:TList
 	Field lastCache:Int = -1
 	Field doneLinks:Int
+	'cache calculated MaxLinkTime()-value for faster lookups
+	Field maxLinkTimeCache:Int = -1
 	
 	' add cc_opts or ld_opts
 	Method AddModOpt(opt:String)
@@ -112,32 +114,45 @@ Type TSourceFile
 		End If
 	End Method
 
-	Method MaxLinkTime:Int(modsOnly:Int = False)
-		Local t:Int
-		
-		If modid Then
-			t = arc_time
-		Else
-			t = obj_time
-		End If
-		If depsList Then
-			For Local s:TSourceFile = EachIn depsList
-				Local st:Int = s.MaxLinkTime(modsOnly)
-				If st > t Then
-					t = st
-				End If
-			Next
+	Method SetRequiresBuild(enable:int)
+		If requiresBuild <> enable Then
+			requiresBuild = enable
+			'seems our information is outdated now
+			If requiresBuild Then
+				maxLinkTimeCache = -1
+			End If
 		End If
-		If moddeps Then
-			For Local s:TSourceFile = EachIn moddeps.Values()
-				Local st:Int = s.MaxLinkTime(True)
-				If st > t Then
-					t = st
-				End If
-			Next
+	End Method
+
+	Method MaxLinkTime:Int(modsOnly:Int = False)
+		If maxLinkTimeCache = -1 Then
+			Local t:Int
+			If modid Then
+				t = arc_time
+			Else
+				t = obj_time
+			End If
+			If depsList Then
+				For Local s:TSourceFile = EachIn depsList
+					Local st:Int = s.MaxLinkTime(modsOnly)
+					If st > t Then
+						t = st
+					End If
+				Next
+			End If
+			If moddeps Then
+				For Local s:TSourceFile = EachIn moddeps.Values()
+					Local st:Int = s.MaxLinkTime(True)
+					If st > t Then
+						t = st
+					End If
+				Next
+			End If
+
+			maxLinkTimeCache = t
 		End If
 
-		Return t
+		Return maxLinkTimeCache
 	End Method
 	
 	Method MakeFatter(list:TList, o_path:String)
@@ -335,6 +350,7 @@ Type TSourceFile
 		source.cpp_opts = cpp_opts
 		source.c_opts = c_opts
 		source.CopyIncludePaths(includePaths)
+		source.maxLinkTimeCache = maxLinkTimeCache
 	End Method
 	
 	Method GetSourcePath:String()