mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Bug 1904995 - Remove redundant dispose loop in for-of loops. r=arai
Differential Revision: https://phabricator.services.mozilla.com/D224253
This commit is contained in:
parent
1e24052171
commit
2fad34600c
@ -5248,7 +5248,21 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitLexicalScope(
|
||||
kind = lexicalScope->kind();
|
||||
}
|
||||
|
||||
if (!lse.emitScope(kind, lexicalScope->scopeBindings())) {
|
||||
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|
||||
EmitterScope::BlockKind blockKind = EmitterScope::BlockKind::Other;
|
||||
if (body->isKind(ParseNodeKind::ForStmt) &&
|
||||
body->as<ForNode>().head()->isKind(ParseNodeKind::ForOf)) {
|
||||
MOZ_ASSERT(kind == ScopeKind::Lexical);
|
||||
blockKind = EmitterScope::BlockKind::ForOf;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!lse.emitScope(kind, lexicalScope->scopeBindings()
|
||||
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|
||||
,
|
||||
blockKind
|
||||
#endif
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -342,7 +342,7 @@ bool EmitterScope::prepareForDisposableScopeBody(BytecodeEmitter* bce) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isSwitchBlock_ == IsSwitchBlock::Yes) {
|
||||
if (blockKind_ == BlockKind::Switch) {
|
||||
// If there are disposables inside the switch case
|
||||
// and if an exception is thrown we would need to unwind
|
||||
// to the environment right before the switch statement for that
|
||||
@ -384,7 +384,7 @@ bool EmitterScope::emitSwitchBlockEndForDisposableScopeBodyEnd(
|
||||
BytecodeEmitter* bce) {
|
||||
MOZ_ASSERT(hasDisposables());
|
||||
|
||||
if (isSwitchBlock_ == IsSwitchBlock::Yes) {
|
||||
if (blockKind_ == BlockKind::Switch) {
|
||||
// See `JSOp::Dup` in EmitterScope::prepareForDisposableScopeBody.
|
||||
if (!bce->emit1(JSOp::Pop)) {
|
||||
return false;
|
||||
@ -409,7 +409,11 @@ bool EmitterScope::emitDisposableScopeBodyEndForNonLocalJump(
|
||||
}
|
||||
|
||||
bool EmitterScope::emitDisposableScopeBodyEnd(BytecodeEmitter* bce) {
|
||||
if (hasDisposables()) {
|
||||
// For-of loops emit the dispose loop in the different place and timing.
|
||||
// (See ForOfEmitter::emitInitialize,
|
||||
// ForOfLoopControl::emitPrepareForNonLocalJumpFromScope and
|
||||
// ForOfLoopControl::emitEndCodeNeedingIteratorClose())
|
||||
if (hasDisposables() && (blockKind_ != BlockKind::ForOf)) {
|
||||
if (!usingEmitter_->emitEnd()) {
|
||||
return false;
|
||||
}
|
||||
@ -430,7 +434,7 @@ bool EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind,
|
||||
LexicalScope::ParserData* bindings
|
||||
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|
||||
,
|
||||
IsSwitchBlock isSwitchBlock
|
||||
BlockKind blockKind
|
||||
#endif
|
||||
) {
|
||||
MOZ_ASSERT(kind != ScopeKind::NamedLambda &&
|
||||
@ -499,7 +503,10 @@ bool EmitterScope::enterLexical(BytecodeEmitter* bce, ScopeKind kind,
|
||||
}
|
||||
|
||||
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|
||||
isSwitchBlock_ = isSwitchBlock;
|
||||
MOZ_ASSERT_IF(blockKind_ != BlockKind::Other, kind == ScopeKind::Lexical);
|
||||
MOZ_ASSERT_IF(kind != ScopeKind::Lexical, blockKind_ == BlockKind::Other);
|
||||
|
||||
blockKind_ = blockKind;
|
||||
|
||||
if (!prepareForDisposableScopeBody(bce)) {
|
||||
return false;
|
||||
|
@ -55,10 +55,10 @@ class EmitterScope : public Nestable<EmitterScope> {
|
||||
mozilla::Maybe<UsingEmitter> usingEmitter_;
|
||||
|
||||
public:
|
||||
enum class IsSwitchBlock : uint8_t { No, Yes };
|
||||
enum class BlockKind : uint8_t { Switch, ForOf, Other };
|
||||
|
||||
private:
|
||||
IsSwitchBlock isSwitchBlock_ = IsSwitchBlock::No;
|
||||
BlockKind blockKind_ = BlockKind::Other;
|
||||
#endif
|
||||
|
||||
// The number of enclosing environments. Used for error checking.
|
||||
@ -134,11 +134,11 @@ class EmitterScope : public Nestable<EmitterScope> {
|
||||
|
||||
void dump(BytecodeEmitter* bce);
|
||||
|
||||
[[nodiscard]] bool enterLexical(
|
||||
BytecodeEmitter* bce, ScopeKind kind, LexicalScope::ParserData* bindings
|
||||
[[nodiscard]] bool enterLexical(BytecodeEmitter* bce, ScopeKind kind,
|
||||
LexicalScope::ParserData* bindings
|
||||
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|
||||
,
|
||||
IsSwitchBlock isSwitchBlock = IsSwitchBlock::No
|
||||
,
|
||||
BlockKind blockKind = BlockKind::Other
|
||||
#endif
|
||||
);
|
||||
[[nodiscard]] bool enterClassBody(BytecodeEmitter* bce, ScopeKind kind,
|
||||
|
@ -12,13 +12,23 @@ using namespace js::frontend;
|
||||
LexicalScopeEmitter::LexicalScopeEmitter(BytecodeEmitter* bce) : bce_(bce) {}
|
||||
|
||||
bool LexicalScopeEmitter::emitScope(ScopeKind kind,
|
||||
LexicalScope::ParserData* bindings) {
|
||||
LexicalScope::ParserData* bindings
|
||||
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|
||||
,
|
||||
EmitterScope::BlockKind blockKind
|
||||
#endif
|
||||
) {
|
||||
MOZ_ASSERT(state_ == State::Start);
|
||||
MOZ_ASSERT(bindings);
|
||||
|
||||
tdzCache_.emplace(bce_);
|
||||
emitterScope_.emplace(bce_);
|
||||
if (!emitterScope_->enterLexical(bce_, kind, bindings)) {
|
||||
if (!emitterScope_->enterLexical(bce_, kind, bindings
|
||||
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|
||||
,
|
||||
blockKind
|
||||
#endif
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -81,8 +81,13 @@ class MOZ_STACK_CLASS LexicalScopeEmitter {
|
||||
// Returns the scope object for non-empty scope.
|
||||
const EmitterScope& emitterScope() const { return *emitterScope_; }
|
||||
|
||||
[[nodiscard]] bool emitScope(ScopeKind kind,
|
||||
LexicalScope::ParserData* bindings);
|
||||
[[nodiscard]] bool emitScope(
|
||||
ScopeKind kind, LexicalScope::ParserData* bindings
|
||||
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|
||||
,
|
||||
EmitterScope::BlockKind blockKind = EmitterScope::BlockKind::Other
|
||||
#endif
|
||||
);
|
||||
[[nodiscard]] bool emitEmptyScope();
|
||||
|
||||
[[nodiscard]] bool emitEnd();
|
||||
|
@ -128,7 +128,7 @@ bool SwitchEmitter::emitLexical(LexicalScope::ParserData* bindings) {
|
||||
if (!emitterScope_->enterLexical(bce_, ScopeKind::Lexical, bindings
|
||||
#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|
||||
,
|
||||
EmitterScope::IsSwitchBlock::Yes
|
||||
EmitterScope::BlockKind::Switch
|
||||
#endif
|
||||
)) {
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user