forked from OSchip/llvm-project
Cache macro expander objects to avoid thrashing malloc in heavy expansion situations.
This doesn't significantly improve carbon.h, but it does speed up INPUTS/macro_pounder_obj.c by 48% llvm-svn: 39864
This commit is contained in:
parent
03928c7f9a
commit
c02c4abe5b
|
@ -233,13 +233,17 @@ const LexerToken &MacroArgs::getStringifiedArgument(unsigned ArgNo,
|
|||
|
||||
/// Create a macro expander for the specified macro with the specified actual
|
||||
/// arguments. Note that this ctor takes ownership of the ActualArgs pointer.
|
||||
MacroExpander::MacroExpander(LexerToken &Tok, MacroArgs *Actuals,
|
||||
Preprocessor &pp)
|
||||
: Macro(Tok.getIdentifierInfo()->getMacroInfo()),
|
||||
ActualArgs(Actuals), PP(pp), CurToken(0),
|
||||
InstantiateLoc(Tok.getLocation()),
|
||||
AtStartOfLine(Tok.isAtStartOfLine()),
|
||||
HasLeadingSpace(Tok.hasLeadingSpace()) {
|
||||
void MacroExpander::Init(LexerToken &Tok, MacroArgs *Actuals) {
|
||||
// If the client is reusing a macro expander, make sure to free any memory
|
||||
// associated with it.
|
||||
destroy();
|
||||
|
||||
Macro = Tok.getIdentifierInfo()->getMacroInfo();
|
||||
ActualArgs = Actuals;
|
||||
CurToken = 0;
|
||||
InstantiateLoc = Tok.getLocation();
|
||||
AtStartOfLine = Tok.isAtStartOfLine();
|
||||
HasLeadingSpace = Tok.hasLeadingSpace();
|
||||
MacroTokens = &*Macro->tokens_begin();
|
||||
NumMacroTokens = Macro->tokens_end()-Macro->tokens_begin();
|
||||
|
||||
|
@ -254,14 +258,23 @@ MacroExpander::MacroExpander(LexerToken &Tok, MacroArgs *Actuals,
|
|||
Macro->DisableMacro();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Create a macro expander for the specified token stream. This does not
|
||||
/// take ownership of the specified token vector.
|
||||
MacroExpander::MacroExpander(const LexerToken *TokArray, unsigned NumToks,
|
||||
Preprocessor &pp)
|
||||
: Macro(0), ActualArgs(0), PP(pp), MacroTokens(TokArray),
|
||||
NumMacroTokens(NumToks), CurToken(0),
|
||||
InstantiateLoc(SourceLocation()), AtStartOfLine(false),
|
||||
HasLeadingSpace(false) {
|
||||
void MacroExpander::Init(const LexerToken *TokArray, unsigned NumToks) {
|
||||
// If the client is reusing a macro expander, make sure to free any memory
|
||||
// associated with it.
|
||||
destroy();
|
||||
|
||||
Macro = 0;
|
||||
ActualArgs = 0;
|
||||
MacroTokens = TokArray;
|
||||
NumMacroTokens = NumToks;
|
||||
CurToken = 0;
|
||||
InstantiateLoc = SourceLocation();
|
||||
AtStartOfLine = false;
|
||||
HasLeadingSpace = false;
|
||||
|
||||
// Set HasLeadingSpace/AtStartOfLine so that the first token will be
|
||||
// returned unmodified.
|
||||
|
@ -272,7 +285,7 @@ MacroExpander::MacroExpander(const LexerToken *TokArray, unsigned NumToks,
|
|||
}
|
||||
|
||||
|
||||
MacroExpander::~MacroExpander() {
|
||||
void MacroExpander::destroy() {
|
||||
// If this was a function-like macro that actually uses its arguments, delete
|
||||
// the expanded tokens.
|
||||
if (Macro && MacroTokens != &*Macro->tokens_begin())
|
||||
|
|
|
@ -48,7 +48,7 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
|
|||
SourceMgr(SM), HeaderInfo(Headers), Identifiers(opts),
|
||||
CurLexer(0), CurDirLookup(0), CurMacroExpander(0), Callbacks(0) {
|
||||
ScratchBuf = new ScratchBuffer(SourceMgr);
|
||||
|
||||
|
||||
// Clear stats.
|
||||
NumDirectives = NumDefined = NumUndefined = NumPragma = 0;
|
||||
NumIf = NumElse = NumEndif = 0;
|
||||
|
@ -65,6 +65,7 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts,
|
|||
// Macro expansion is enabled.
|
||||
DisableMacroExpansion = false;
|
||||
InMacroArgs = false;
|
||||
NumCachedMacroExpanders = 0;
|
||||
|
||||
// "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
|
||||
// This gets unpoisoned where it is allowed.
|
||||
|
@ -88,6 +89,10 @@ Preprocessor::~Preprocessor() {
|
|||
IncludeMacroStack.pop_back();
|
||||
}
|
||||
|
||||
// Free any cached macro expanders.
|
||||
for (unsigned i = 0, e = NumCachedMacroExpanders; i != e; ++i)
|
||||
delete MacroExpanderCache[i];
|
||||
|
||||
// Release pragma information.
|
||||
delete PragmaHandlers;
|
||||
|
||||
|
@ -386,7 +391,12 @@ void Preprocessor::EnterMacro(LexerToken &Tok, MacroArgs *Args) {
|
|||
CurLexer = 0;
|
||||
CurDirLookup = 0;
|
||||
|
||||
CurMacroExpander = new MacroExpander(Tok, Args, *this);
|
||||
if (NumCachedMacroExpanders == 0) {
|
||||
CurMacroExpander = new MacroExpander(Tok, Args, *this);
|
||||
} else {
|
||||
CurMacroExpander = MacroExpanderCache[--NumCachedMacroExpanders];
|
||||
CurMacroExpander->Init(Tok, Args);
|
||||
}
|
||||
}
|
||||
|
||||
/// EnterTokenStream - Add a "macro" context to the top of the include stack,
|
||||
|
@ -402,7 +412,12 @@ void Preprocessor::EnterTokenStream(const LexerToken *Toks, unsigned NumToks) {
|
|||
CurDirLookup = 0;
|
||||
|
||||
// Create a macro expander to expand from the specified token stream.
|
||||
CurMacroExpander = new MacroExpander(Toks, NumToks, *this);
|
||||
if (NumCachedMacroExpanders == 0) {
|
||||
CurMacroExpander = new MacroExpander(Toks, NumToks, *this);
|
||||
} else {
|
||||
CurMacroExpander = MacroExpanderCache[--NumCachedMacroExpanders];
|
||||
CurMacroExpander->Init(Toks, NumToks);
|
||||
}
|
||||
}
|
||||
|
||||
/// RemoveTopOfLexerStack - Pop the current lexer/macro exp off the top of the
|
||||
|
@ -410,8 +425,16 @@ void Preprocessor::EnterTokenStream(const LexerToken *Toks, unsigned NumToks) {
|
|||
/// state of the top-of-stack lexer is known.
|
||||
void Preprocessor::RemoveTopOfLexerStack() {
|
||||
assert(!IncludeMacroStack.empty() && "Ran out of stack entries to load");
|
||||
delete CurLexer;
|
||||
delete CurMacroExpander;
|
||||
|
||||
if (CurMacroExpander) {
|
||||
// Delete or cache the now-dead macro expander.
|
||||
if (NumCachedMacroExpanders == MacroExpanderCacheSize)
|
||||
delete CurMacroExpander;
|
||||
else
|
||||
MacroExpanderCache[NumCachedMacroExpanders++] = CurMacroExpander;
|
||||
} else {
|
||||
delete CurLexer;
|
||||
}
|
||||
CurLexer = IncludeMacroStack.back().TheLexer;
|
||||
CurDirLookup = IncludeMacroStack.back().TheDirLookup;
|
||||
CurMacroExpander = IncludeMacroStack.back().TheMacroExpander;
|
||||
|
@ -1047,7 +1070,11 @@ bool Preprocessor::HandleEndOfMacro(LexerToken &Result) {
|
|||
assert(CurMacroExpander && !CurLexer &&
|
||||
"Ending a macro when currently in a #include file!");
|
||||
|
||||
delete CurMacroExpander;
|
||||
// Delete or cache the now-dead macro expander.
|
||||
if (NumCachedMacroExpanders == MacroExpanderCacheSize)
|
||||
delete CurMacroExpander;
|
||||
else
|
||||
MacroExpanderCache[NumCachedMacroExpanders++] = CurMacroExpander;
|
||||
|
||||
// Handle this like a #include file being popped off the stack.
|
||||
CurMacroExpander = 0;
|
||||
|
|
|
@ -141,12 +141,28 @@ class MacroExpander {
|
|||
public:
|
||||
/// Create a macro expander for the specified macro with the specified actual
|
||||
/// arguments. Note that this ctor takes ownership of the ActualArgs pointer.
|
||||
MacroExpander(LexerToken &Tok, MacroArgs *ActualArgs, Preprocessor &PP);
|
||||
MacroExpander(LexerToken &Tok, MacroArgs *ActualArgs, Preprocessor &pp)
|
||||
: Macro(0), ActualArgs(0), PP(pp) {
|
||||
Init(Tok, ActualArgs);
|
||||
}
|
||||
|
||||
/// Init - Initialize this macro expander to expand from the specified macro
|
||||
/// with the specified argument information. Note that this ctor takes
|
||||
/// ownership of the ActualArgs pointer.
|
||||
void Init(LexerToken &Tok, MacroArgs *ActualArgs);
|
||||
|
||||
/// Create a macro expander for the specified token stream. This does not
|
||||
/// take ownership of the specified token vector.
|
||||
MacroExpander(const LexerToken *TokArray, unsigned NumToks, Preprocessor &PP);
|
||||
~MacroExpander();
|
||||
MacroExpander(const LexerToken *TokArray, unsigned NumToks, Preprocessor &pp)
|
||||
: Macro(0), ActualArgs(0), PP(pp) {
|
||||
Init(TokArray, NumToks);
|
||||
}
|
||||
|
||||
/// Init - Initialize this macro expander with the specified token stream.
|
||||
/// This does not take ownership of the specified token vector.
|
||||
void Init(const LexerToken *TokArray, unsigned NumToks);
|
||||
|
||||
~MacroExpander() { destroy(); }
|
||||
|
||||
/// isNextTokenLParen - If the next token lexed will pop this macro off the
|
||||
/// expansion stack, return 2. If the next unexpanded token is a '(', return
|
||||
|
@ -157,6 +173,8 @@ public:
|
|||
void Lex(LexerToken &Tok);
|
||||
|
||||
private:
|
||||
void destroy();
|
||||
|
||||
/// isAtEnd - Return true if the next lex call will pop this macro off the
|
||||
/// include stack.
|
||||
bool isAtEnd() const {
|
||||
|
|
|
@ -114,6 +114,11 @@ class Preprocessor {
|
|||
unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
|
||||
unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
|
||||
unsigned NumSkipped;
|
||||
|
||||
/// MacroExpanderCache - Cache macro expanders to reduce malloc traffic.
|
||||
enum { MacroExpanderCacheSize = 8 };
|
||||
unsigned NumCachedMacroExpanders;
|
||||
MacroExpander *MacroExpanderCache[MacroExpanderCacheSize];
|
||||
public:
|
||||
Preprocessor(Diagnostic &diags, const LangOptions &opts, TargetInfo &target,
|
||||
SourceManager &SM, HeaderSearch &Headers);
|
||||
|
|
Loading…
Reference in New Issue