Bug 1569315 - Clarify GC status of FunctionCreationData r=tcampbell

Differential Revision: https://phabricator.services.mozilla.com/D40507

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matthew Gaudet 2019-08-06 21:02:35 +00:00
parent 4925a59731
commit 969004e3aa
4 changed files with 70 additions and 56 deletions

View File

@ -334,9 +334,9 @@ FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
template <class ParseHandler>
FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
FunctionNodeType funNode, FunctionCreationData& fcd, uint32_t toStringStart,
Directives inheritedDirectives, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind) {
FunctionNodeType funNode, Handle<FunctionCreationData> fcd,
uint32_t toStringStart, Directives inheritedDirectives,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
/*
* We use JSContext.tempLifoAlloc to allocate parsed objects and place them
* on a list in this Parser to ensure GC safety. Thus the tempLifoAlloc
@ -351,8 +351,7 @@ FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
cx_, traceListHead_, fcd, toStringStart, inheritedDirectives,
options().extraWarningsOption, generatorKind, asyncKind);
} else {
Rooted<FunctionCreationData> functionData(cx_, fcd);
RootedFunction fun(cx_, AllocNewFunction(cx_, functionData));
RootedFunction fun(cx_, AllocNewFunction(cx_, fcd));
if (!fun) {
ReportOutOfMemory(cx_);
return nullptr;
@ -1795,13 +1794,11 @@ bool ParserBase::publishDeferredFunctions(FunctionTree* root) {
return true;
}
if (!funbox->functionCreationData().isSome()) {
if (!funbox->functionCreationData()) {
return true;
}
Rooted<FunctionCreationData> fcd(parser->cx_,
*funbox->functionCreationData());
Handle<FunctionCreationData> fcd = funbox->functionCreationDataHandle();
RootedFunction fun(parser->cx_, AllocNewFunction(parser->cx_, fcd));
if (!fun) {
return false;
@ -2779,9 +2776,10 @@ GeneralParser<ParseHandler, Unit>::functionDefinition(
return funNode;
}
FunctionCreationData fcd = GenerateFunctionCreationData(
funName, kind, generatorKind, asyncKind, options().selfHostingMode,
pc_->isFunctionBox());
Rooted<FunctionCreationData> fcd(
cx_, GenerateFunctionCreationData(funName, kind, generatorKind, asyncKind,
options().selfHostingMode,
pc_->isFunctionBox()));
// Speculatively parse using the directives of the parent parsing context.
// If a directive is encountered (e.g., "use strict") that changes how the
@ -2825,10 +2823,11 @@ GeneralParser<ParseHandler, Unit>::functionDefinition(
template <typename Unit>
bool Parser<FullParseHandler, Unit>::trySyntaxParseInnerFunction(
FunctionNode** funNode, FunctionCreationData& fcd, uint32_t toStringStart,
InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives) {
FunctionNode** funNode, Handle<FunctionCreationData> fcd,
uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
FunctionSyntaxKind kind, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
Directives* newDirectives) {
// Try a syntax parse for this inner function.
do {
// If we're assuming this function is an IIFE, always perform a full
@ -2920,7 +2919,7 @@ bool Parser<FullParseHandler, Unit>::trySyntaxParseInnerFunction(
template <typename Unit>
bool Parser<SyntaxParseHandler, Unit>::trySyntaxParseInnerFunction(
FunctionNodeType* funNode, FunctionCreationData& fcd,
FunctionNodeType* funNode, Handle<FunctionCreationData> fcd,
uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
FunctionSyntaxKind kind, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
@ -2940,7 +2939,7 @@ bool Parser<SyntaxParseHandler, Unit>::trySyntaxParseInnerFunction(
template <class ParseHandler, typename Unit>
inline bool GeneralParser<ParseHandler, Unit>::trySyntaxParseInnerFunction(
FunctionNodeType* funNode, FunctionCreationData& fcd,
FunctionNodeType* funNode, Handle<FunctionCreationData> fcd,
uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
FunctionSyntaxKind kind, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
@ -2982,11 +2981,11 @@ GeneralParser<ParseHandler, Unit>::innerFunctionForFunctionBox(
template <class ParseHandler, typename Unit>
typename ParseHandler::FunctionNodeType
GeneralParser<ParseHandler, Unit>::innerFunction(
FunctionNodeType funNode, ParseContext* outerpc, FunctionCreationData& fcd,
uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
FunctionSyntaxKind kind, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
Directives* newDirectives) {
FunctionNodeType funNode, ParseContext* outerpc,
Handle<FunctionCreationData> fcd, uint32_t toStringStart,
InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives) {
// Note that it is possible for outerpc != this->pc_, as we may be
// attempting to syntax parse an inner function from an outer full
// parser. In that case, outerpc is a SourceParseContext from the full parser
@ -7377,10 +7376,11 @@ GeneralParser<ParseHandler, Unit>::synthesizeConstructor(
? FunctionSyntaxKind::DerivedClassConstructor
: FunctionSyntaxKind::ClassConstructor;
FunctionCreationData data = GenerateFunctionCreationData(
className, functionSyntaxKind, GeneratorKind::NotGenerator,
FunctionAsyncKind::SyncFunction, options().selfHostingMode,
pc_->isFunctionBox());
Rooted<FunctionCreationData> data(
cx_, GenerateFunctionCreationData(
className, functionSyntaxKind, GeneratorKind::NotGenerator,
FunctionAsyncKind::SyncFunction, options().selfHostingMode,
pc_->isFunctionBox()));
// Create the top-level field initializer node.
FunctionNodeType funNode = handler_.newFunction(functionSyntaxKind, pos());
@ -7546,10 +7546,11 @@ GeneralParser<ParseHandler, Unit>::fieldInitializerOpt(
firstTokenPos = TokenPos(endPos, endPos);
}
FunctionCreationData data = GenerateFunctionCreationData(
nullptr, FunctionSyntaxKind::Method, GeneratorKind::NotGenerator,
FunctionAsyncKind::SyncFunction, options().selfHostingMode,
pc_->isFunctionBox());
Rooted<FunctionCreationData> data(
cx_, GenerateFunctionCreationData(
nullptr, FunctionSyntaxKind::Method, GeneratorKind::NotGenerator,
FunctionAsyncKind::SyncFunction, options().selfHostingMode,
pc_->isFunctionBox()));
// Create the top-level field initializer node.
FunctionNodeType funNode =

View File

@ -730,8 +730,8 @@ class MOZ_STACK_CLASS PerHandlerParser : public ParserBase {
FunctionAsyncKind asyncKind);
FunctionBox* newFunctionBox(FunctionNodeType funNode,
FunctionCreationData& fcd, uint32_t toStringStart,
Directives directives,
Handle<FunctionCreationData> fcd,
uint32_t toStringStart, Directives directives,
GeneratorKind generatorKind,
FunctionAsyncKind asyncKind);
@ -1164,7 +1164,7 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
ListNodeType nodeList, TokenKind* ttp);
inline bool trySyntaxParseInnerFunction(
FunctionNodeType* funNode, FunctionCreationData& fcd,
FunctionNodeType* funNode, Handle<FunctionCreationData> fcd,
uint32_t toStringStart, InHandling inHandling,
YieldHandling yieldHandling, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
@ -1543,12 +1543,13 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
ListNodeType statementList(YieldHandling yieldHandling);
MOZ_MUST_USE FunctionNodeType innerFunction(
FunctionNodeType funNode, ParseContext* outerpc,
FunctionCreationData& fcd, uint32_t toStringStart, InHandling inHandling,
YieldHandling yieldHandling, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
MOZ_MUST_USE FunctionNodeType
innerFunction(FunctionNodeType funNode, ParseContext* outerpc,
Handle<FunctionCreationData> fcd, uint32_t toStringStart,
InHandling inHandling, YieldHandling yieldHandling,
FunctionSyntaxKind kind, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
// Implements Automatic Semicolon Insertion.
//
@ -1699,7 +1700,7 @@ class MOZ_STACK_CLASS Parser<SyntaxParseHandler, Unit> final
inline bool checkExportedNameForClause(NameNodeType nameNode);
bool trySyntaxParseInnerFunction(
FunctionNodeType* funNode, FunctionCreationData& fcd,
FunctionNodeType* funNode, Handle<FunctionCreationData> fcd,
uint32_t toStringStart, InHandling inHandling,
YieldHandling yieldHandling, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
@ -1852,7 +1853,7 @@ class MOZ_STACK_CLASS Parser<FullParseHandler, Unit> final
inline bool checkExportedNameForClause(NameNodeType nameNode);
bool trySyntaxParseInnerFunction(
FunctionNodeType* funNode, FunctionCreationData& fcd,
FunctionNodeType* funNode, Handle<FunctionCreationData> fcd,
uint32_t toStringStart, InHandling inHandling,
YieldHandling yieldHandling, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,

View File

@ -188,16 +188,17 @@ FunctionBox::FunctionBox(JSContext* cx, TraceListNode* traceListHead,
}
FunctionBox::FunctionBox(JSContext* cx, TraceListNode* traceListHead,
FunctionCreationData& data, uint32_t toStringStart,
Directives directives, bool extraWarnings,
GeneratorKind generatorKind,
Handle<FunctionCreationData> data,
uint32_t toStringStart, Directives directives,
bool extraWarnings, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind)
: FunctionBox(cx, traceListHead, toStringStart, directives, extraWarnings,
generatorKind, asyncKind, data.flags.isArrow(),
data.isNamedLambda(), data.flags.isGetter(),
data.flags.isSetter(), data.flags.isMethod(),
data.flags.isInterpreted(), data.flags.isInterpretedLazy(),
data.flags.kind(), data.atom) {
generatorKind, asyncKind, data.get().flags.isArrow(),
data.get().isNamedLambda(), data.get().flags.isGetter(),
data.get().flags.isSetter(), data.get().flags.isMethod(),
data.get().flags.isInterpreted(),
data.get().flags.isInterpretedLazy(), data.get().flags.kind(),
data.get().atom) {
functionCreationData_.emplace(data);
}
@ -272,7 +273,7 @@ void FunctionBox::initWithEnclosingParseContext(ParseContext* enclosing,
}
void FunctionBox::initFieldInitializer(ParseContext* enclosing,
FunctionCreationData& data,
Handle<FunctionCreationData> data,
HasHeritage hasHeritage) {
this->initWithEnclosingParseContext(enclosing, data,
FunctionSyntaxKind::Expression);

View File

@ -447,6 +447,9 @@ class FunctionBox : public ObjectBox, public SharedContext {
}
mozilla::Maybe<FunctionCreationData> functionCreationData_;
bool hasFunctionCreationData() { return functionCreationData_.isSome(); }
const mozilla::Maybe<FunctionCreationData>& functionCreationData() const {
return functionCreationData_;
}
@ -454,12 +457,19 @@ class FunctionBox : public ObjectBox, public SharedContext {
return functionCreationData_;
}
Handle<FunctionCreationData> functionCreationDataHandle() {
// This is safe because the FunctionCreationData are marked
// via ParserBase -> FunctionBox -> FunctionCreationData.
return Handle<FunctionCreationData>::fromMarkedLocation(
functionCreationData_.ptr());
}
FunctionBox(JSContext* cx, TraceListNode* traceListHead, JSFunction* fun,
uint32_t toStringStart, Directives directives, bool extraWarnings,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
FunctionBox(JSContext* cx, TraceListNode* traceListHead,
FunctionCreationData& data, uint32_t toStringStart,
Handle<FunctionCreationData> data, uint32_t toStringStart,
Directives directives, bool extraWarnings,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
@ -489,10 +499,10 @@ class FunctionBox : public ObjectBox, public SharedContext {
void initStandaloneFunction(Scope* enclosingScope);
void initWithEnclosingParseContext(ParseContext* enclosing,
FunctionCreationData& fun,
Handle<FunctionCreationData> fun,
FunctionSyntaxKind kind) {
initWithEnclosingParseContext(enclosing, kind, fun.flags.isArrow(),
fun.flags.allowSuperProperty());
initWithEnclosingParseContext(enclosing, kind, fun.get().flags.isArrow(),
fun.get().flags.allowSuperProperty());
}
void initWithEnclosingParseContext(ParseContext* enclosing, JSFunction* fun,
@ -503,7 +513,8 @@ class FunctionBox : public ObjectBox, public SharedContext {
void initFieldInitializer(ParseContext* enclosing, JSFunction* fun,
HasHeritage hasHeritage);
void initFieldInitializer(ParseContext* enclosing, FunctionCreationData& data,
void initFieldInitializer(ParseContext* enclosing,
Handle<FunctionCreationData> data,
HasHeritage hasHeritage);
inline bool isLazyFunctionWithoutEnclosingScope() const {