From: BobCF <bob.c.feng@intel.com>
To: edk2-devel@lists.01.org
Cc: Liming Gao <liming.gao@intel.com>, Jaben Carsey <jaben.carsey@intel.com>
Subject: [Patch] BaseTools: Customize deepcopy function.
Date: Thu, 8 Nov 2018 14:03:38 +0800 [thread overview]
Message-ID: <20181108060338.40404-1-bob.c.feng@intel.com> (raw)
https://bugzilla.tianocore.org/show_bug.cgi?id=1288
This patch is one of build tool performance improvement
series patches.
This patch is going to customize the deepcopy function for
SkuClass, PcdClassObject and python dictionary.
python deepcopy copy everything of a object, but for our current
usage we just need to copy the data we care about recursively.
By implementing __deepcopy__ for SkuClass, PcdClassObject, we can customize
deepcopy function for them.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: BobCF <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Jaben Carsey <jaben.carsey@intel.com>
---
BaseTools/Source/Python/Common/Expression.py | 4 +-
BaseTools/Source/Python/Common/Misc.py | 16 ++++++
.../Python/CommonDataClass/CommonClass.py | 15 ++++++
.../Python/Workspace/BuildClassObject.py | 52 +++++++++++++++++++
.../Source/Python/Workspace/DscBuildData.py | 6 +--
5 files changed, 88 insertions(+), 5 deletions(-)
diff --git a/BaseTools/Source/Python/Common/Expression.py b/BaseTools/Source/Python/Common/Expression.py
index a21ab5daa7..091c0f4296 100644
--- a/BaseTools/Source/Python/Common/Expression.py
+++ b/BaseTools/Source/Python/Common/Expression.py
@@ -15,11 +15,11 @@
from __future__ import print_function
from __future__ import absolute_import
from Common.GlobalData import *
from CommonDataClass.Exceptions import BadExpression
from CommonDataClass.Exceptions import WrnExpression
-from .Misc import GuidStringToGuidStructureString, ParseFieldValue
+from .Misc import GuidStringToGuidStructureString, ParseFieldValue,CopyDict
import Common.EdkLogger as EdkLogger
import copy
from Common.DataType import *
import sys
from random import sample
@@ -353,11 +353,11 @@ class ValueExpression(BaseExpression):
raise BadExpression(ERR_EMPTY_EXPR)
#
# The symbol table including PCD and macro mapping
#
- self._Symb = copy.deepcopy(SymbolTable)
+ self._Symb = CopyDict(SymbolTable)
self._Symb.update(self.LogicalOperators)
self._Idx = 0
self._Len = len(self._Expr)
self._Token = ''
self._WarnExcept = None
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index 3b8efb2e71..80236db160 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -39,10 +39,11 @@ from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
import uuid
from CommonDataClass.Exceptions import BadExpression
from Common.caching import cached_property
import subprocess
+from collections import OrderedDict
## Regular expression used to find out place holders in string template
gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)
## regular expressions for map file processing
startPatternGeneral = re.compile("^Start[' ']+Length[' ']+Name[' ']+Class")
@@ -2129,10 +2130,25 @@ def PackByteFormatGUID(Guid):
Guid[8],
Guid[9],
Guid[10],
)
+## DeepCopy dict/OrderedDict recusively
+#
+# @param ori_dict a nested dict or ordereddict
+#
+# @retval new dict or orderdict
+#
+def CopyDict(ori_dict):
+ dict_type = ori_dict.__class__
+ new_dict = dict_type()
+ for key in ori_dict:
+ if isinstance(ori_dict[key],(dict,OrderedDict)):
+ new_dict[key] = CopyDict(ori_dict[key])
+ else:
+ new_dict[key] = ori_dict[key]
+ return new_dict
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
diff --git a/BaseTools/Source/Python/CommonDataClass/CommonClass.py b/BaseTools/Source/Python/CommonDataClass/CommonClass.py
index a98cf8a7c5..336bb11671 100644
--- a/BaseTools/Source/Python/CommonDataClass/CommonClass.py
+++ b/BaseTools/Source/Python/CommonDataClass/CommonClass.py
@@ -78,5 +78,20 @@ class SkuInfoClass(object):
'VariableOffset = ' + str(self.VariableOffset) + "," + \
'HiiDefaultValue = ' + str(self.HiiDefaultValue) + "," + \
'VpdOffset = ' + str(self.VpdOffset) + "," + \
'DefaultValue = ' + str(self.DefaultValue) + ","
return Rtn
+
+ def __deepcopy__(self,memo):
+ new_sku = SkuInfoClass()
+ new_sku.SkuIdName = self.SkuIdName
+ new_sku.SkuId = self.SkuId
+ new_sku.VariableName = self.VariableName
+ new_sku.VariableGuid = self.VariableGuid
+ new_sku.VariableGuidValue = self.VariableGuidValue
+ new_sku.VariableOffset = self.VariableOffset
+ new_sku.HiiDefaultValue = self.HiiDefaultValue
+ new_sku.VariableAttribute = self.VariableAttribute
+ new_sku.DefaultStoreDict = {key:value for key,value in self.DefaultStoreDict.items()}
+ new_sku.VpdOffset = self.VpdOffset
+ new_sku.DefaultValue = self.DefaultValue
+ return new_sku
diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py
index 95edc376fe..7d10391c1e 100644
--- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
+++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
@@ -14,10 +14,12 @@
from collections import OrderedDict, namedtuple
from Common.DataType import *
import collections
import re
from collections import OrderedDict
+from Common.Misc import CopyDict
+import copy
StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_\[\]]*$')
ArrayIndex = re.compile("\[\s*\d{0,1}\s*\]")
## PcdClassObject
#
# This Class is used for PcdObject
@@ -152,10 +154,41 @@ class PcdClassObject(object):
# @retval truple() Key for hash table
#
def __hash__(self):
return hash((self.TokenCName, self.TokenSpaceGuidCName))
+ def sharedcopy(self,new_pcd):
+ new_pcd.TokenCName = self.TokenCName
+ new_pcd.TokenSpaceGuidCName = self.TokenSpaceGuidCName
+ new_pcd.TokenSpaceGuidValue = self.TokenSpaceGuidValue
+ new_pcd.Type = self.Type
+ new_pcd.DatumType = self.DatumType
+ new_pcd.DefaultValue = self.DefaultValue
+ new_pcd.TokenValue = self.TokenValue
+ new_pcd.MaxDatumSize = self.MaxDatumSize
+
+ new_pcd.Phase = self.Phase
+ new_pcd.Pending = self.Pending
+ new_pcd.IsOverrided = self.IsOverrided
+ new_pcd.IsFromBinaryInf = self.IsFromBinaryInf
+ new_pcd.IsFromDsc = self.IsFromDsc
+ new_pcd.PcdValueFromComm = self.PcdValueFromComm
+ new_pcd.PcdValueFromFdf = self.PcdValueFromFdf
+ new_pcd.UserDefinedDefaultStoresFlag = self.UserDefinedDefaultStoresFlag
+ new_pcd.DscRawValue = self.DscRawValue
+ new_pcd.CustomAttribute = self.CustomAttribute
+ new_pcd.validateranges = [item for item in self.validateranges]
+ new_pcd.validlists = [item for item in self.validlists]
+ new_pcd.expressions = [item for item in self.expressions]
+ new_pcd.SkuInfoList = {key: copy.deepcopy(skuobj) for key,skuobj in self.SkuInfoList.items()}
+ return new_pcd
+
+ def __deepcopy__(self,memo):
+ new_pcd = PcdClassObject()
+ self.sharedcopy(new_pcd)
+ return new_pcd
+
class StructurePcd(PcdClassObject):
def __init__(self, StructuredPcdIncludeFile=None, Packages=None, Name=None, Guid=None, Type=None, DatumType=None, Value=None, Token=None, MaxDatumSize=None, SkuInfoList=None, IsOverrided=False, GuidValue=None, validateranges=None, validlists=None, expressions=None,default_store = TAB_DEFAULT_STORES_DEFAULT):
if SkuInfoList is None:
SkuInfoList = {}
if validateranges is None:
@@ -240,10 +273,29 @@ class StructurePcd(PcdClassObject):
self.PkgPath = PcdObject.PkgPath if PcdObject.PkgPath else self.PkgPath
self.ValueChain = PcdObject.ValueChain if PcdObject.ValueChain else self.ValueChain
self.PcdFieldValueFromComm = PcdObject.PcdFieldValueFromComm if PcdObject.PcdFieldValueFromComm else self.PcdFieldValueFromComm
self.PcdFieldValueFromFdf = PcdObject.PcdFieldValueFromFdf if PcdObject.PcdFieldValueFromFdf else self.PcdFieldValueFromFdf
+ def __deepcopy__(self,memo):
+ new_pcd = StructurePcd()
+ self.sharedcopy(new_pcd)
+
+ new_pcd.DefaultValueFromDec = self.DefaultValueFromDec
+ new_pcd.PcdMode = self.PcdMode
+ new_pcd.StructName = self.DatumType
+ new_pcd.PcdDefineLineNo = self.PcdDefineLineNo
+ new_pcd.PkgPath = self.PkgPath
+ new_pcd.StructuredPcdIncludeFile = [item for item in self.StructuredPcdIncludeFile]
+ new_pcd.PackageDecs = [item for item in self.PackageDecs]
+ new_pcd.DefaultValues = CopyDict(self.DefaultValues)
+ new_pcd.DefaultFromDSC=CopyDict(self.DefaultFromDSC)
+ new_pcd.SkuOverrideValues = CopyDict(self.SkuOverrideValues)
+ new_pcd.PcdFieldValueFromComm = CopyDict(self.PcdFieldValueFromComm)
+ new_pcd.PcdFieldValueFromFdf = CopyDict(self.PcdFieldValueFromFdf)
+ new_pcd.ValueChain = {item for item in self.ValueChain}
+ return new_pcd
+
LibraryClassObject = namedtuple('LibraryClassObject', ['LibraryClass','SupModList'], verbose=False)
## ModuleBuildClassObject
#
# This Class defines ModuleBuildClass
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 11aa63fb26..5655034b88 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -970,11 +970,11 @@ class DscBuildData(PlatformBuildClassObject):
for skuid in pcd.SkuInfoList:
skuobj = pcd.SkuInfoList.get(skuid)
if TAB_DEFAULT_STORES_DEFAULT not in skuobj.DefaultStoreDict:
PcdDefaultStoreSet = set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict)
mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
- skuobj.DefaultStoreDict[TAB_DEFAULT_STORES_DEFAULT] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
+ skuobj.DefaultStoreDict[TAB_DEFAULT_STORES_DEFAULT] = CopyDict(skuobj.DefaultStoreDict[mindefaultstorename])
return Pcds
def RecoverCommandLinePcd(self):
def UpdateCommandLineValue(pcd):
if pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
@@ -1501,11 +1501,11 @@ class DscBuildData(PlatformBuildClassObject):
PcdDefaultStoreSet = set(defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[nextskuid])
mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
for defaultstoreid in DefaultStores:
if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]:
- stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
+ stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = CopyDict(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename])
stru_pcd.ValueChain.add((skuid, defaultstoreid))
S_pcd_set = DscBuildData.OverrideByFdf(S_pcd_set,self.WorkspaceDir)
S_pcd_set = DscBuildData.OverrideByComm(S_pcd_set)
Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set)
if Str_Pcd_Values:
@@ -2597,11 +2597,11 @@ class DscBuildData(PlatformBuildClassObject):
for skuid in PcdObj.SkuInfoList:
skuobj = PcdObj.SkuInfoList[skuid]
mindefaultstorename = DefaultStoreObj.GetMin(set(defaultstorename for defaultstorename in skuobj.DefaultStoreDict))
for defaultstorename in DefaultStores:
if defaultstorename not in skuobj.DefaultStoreDict:
- skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
+ skuobj.DefaultStoreDict[defaultstorename] = CopyDict(skuobj.DefaultStoreDict[mindefaultstorename])
skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename]
for skuname, skuid in SkuIds.items():
if skuname not in PcdObj.SkuInfoList:
nextskuid = self.SkuIdMgr.GetNextSkuId(skuname)
while nextskuid not in PcdObj.SkuInfoList:
--
2.19.1.windows.1
next reply other threads:[~2018-11-08 6:03 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-08 6:03 BobCF [this message]
2018-11-08 15:22 ` [Patch] BaseTools: Customize deepcopy function Carsey, Jaben
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181108060338.40404-1-bob.c.feng@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox