Ignore:
Timestamp:
Oct 2, 2019, 2:23:09 PM (6 years ago)
Author:
[email protected]
Message:

[JSC] AsyncGenerator should have internal fields
https://bugs.webkit.org/show_bug.cgi?id=201498

Reviewed by Saam Barati.

JSTests:

  • stress/async-generator-construct-failure.js: Added.

(shouldThrow):
(async.gen):
(TypeError):

  • stress/async-generator-prototype-change.js: Added.

(shouldBe):
(async.gen):

  • stress/async-generator-prototype-closure.js: Added.

(shouldBe):
(test.async.gen):
(test):

  • stress/create-async-generator.js: Added.

(shouldBe):
(test.async.generator):
(test):

Source/JavaScriptCore:

This patch introduces JSAsyncGenerator. We did this already for JSGenerator. This patch does the same thing for JSAsyncGenerator
This patch cleans up JSGenerator's code to share it with JSAsyncGenerator, e.g. JSGenerator::initialValues etc.
It improves JetStream2/async-fs by ~10%.

We also fixed the pre-existing bug. We are using OpcodeID for the key of hashmap. And using op_add code as a part of key.
By adding a new bytecode, it suddenly becomes 0. And 0 is not valid key in WTF::HashMap. This patch adds 1 to opcodeID when using
for HashMap's key to fix this issue.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Sources.txt:
  • builtins/AsyncGeneratorPrototype.js:

(globalPrivate.asyncGeneratorQueueIsEmpty):
(globalPrivate.asyncGeneratorQueueEnqueue):
(globalPrivate.asyncGeneratorQueueDequeue):
(globalPrivate.isExecutionState):
(globalPrivate.isSuspendYieldState):
(globalPrivate.asyncGeneratorReject):
(globalPrivate.asyncGeneratorResolve):
(asyncGeneratorYieldAwaited):
(globalPrivate.asyncGeneratorYield):
(globalPrivate.doAsyncGeneratorBodyCall):
(globalPrivate.asyncGeneratorResumeNext):
(globalPrivate.asyncGeneratorEnqueue):

  • builtins/BuiltinNames.h:
  • bytecode/BytecodeIntrinsicRegistry.cpp:

(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):

  • bytecode/BytecodeIntrinsicRegistry.h:
  • bytecode/BytecodeList.rb:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::finalizeLLIntInlineCaches):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitPutAsyncGeneratorFields):
(JSC::BytecodeGenerator::emitCreateAsyncGenerator):
(JSC::BytecodeGenerator::emitYieldPoint):
(JSC::BytecodeGenerator::emitYield):
(JSC::BytecodeGenerator::emitAwait):
(JSC::BytecodeGenerator::emitDelegateYield):
(JSC::BytecodeGenerator::emitGeneratorStateChange):

  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::emitIsAsyncGenerator):

  • bytecompiler/NodesCodegen.cpp:

(JSC::asyncGeneratorInternalFieldIndex):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_getAsyncGeneratorInternalField):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_putAsyncGeneratorInternalField):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_isAsyncGenerator):
(JSC::YieldExprNode::emitBytecode):
(JSC::AwaitExprNode::emitBytecode):

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::handleCreateInternalFieldObject):

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::capabilityLevel):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGClobbersExitState.cpp:

(JSC::DFG::clobbersExitState):

  • dfg/DFGConstantFoldingPhase.cpp:

(JSC::DFG::ConstantFoldingPhase::foldConstants):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGNode.h:

(JSC::DFG::Node::convertToNewInternalFieldObject):
(JSC::DFG::Node::hasStructure):
(JSC::DFG::Node::convertToNewGenerator): Deleted.

  • dfg/DFGNodeType.h:
  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:
  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileCreateInternalFieldObject):
(JSC::DFG::SpeculativeJIT::compileCreateGenerator):
(JSC::DFG::SpeculativeJIT::compileCreateAsyncGenerator):
(JSC::DFG::SpeculativeJIT::compileNewInternalFieldObject):
(JSC::DFG::SpeculativeJIT::compileNewGenerator):
(JSC::DFG::SpeculativeJIT::compileNewAsyncGenerator):

  • dfg/DFGSpeculativeJIT.h:
  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGStoreBarrierInsertionPhase.cpp:
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileNewInternalFieldObject):
(JSC::FTL::DFG::LowerDFGToB3::compileNewGenerator):
(JSC::FTL::DFG::LowerDFGToB3::compileNewAsyncGenerator):
(JSC::FTL::DFG::LowerDFGToB3::compileCreateInternalFieldObject):
(JSC::FTL::DFG::LowerDFGToB3::compileCreateGenerator):
(JSC::FTL::DFG::LowerDFGToB3::compileCreateAsyncGenerator):

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):

  • jit/JITInlines.h:

(JSC::JIT::copiedArithProfile):

  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • llint/LowLevelInterpreter.asm:
  • runtime/CommonSlowPaths.cpp:

(JSC::createInternalFieldObject):
(JSC::SLOW_PATH_DECL):

  • runtime/CommonSlowPaths.h:
  • runtime/JSAsyncGenerator.cpp: Copied from Source/JavaScriptCore/runtime/JSGenerator.cpp.

(JSC::JSAsyncGenerator::create):
(JSC::JSAsyncGenerator::createStructure):
(JSC::JSAsyncGenerator::JSAsyncGenerator):
(JSC::JSAsyncGenerator::finishCreation):
(JSC::JSAsyncGenerator::visitChildren):

  • runtime/JSAsyncGenerator.h: Copied from Source/JavaScriptCore/runtime/JSGenerator.h.
  • runtime/JSAsyncGeneratorFunction.h:
  • runtime/JSGenerator.cpp:

(JSC::JSGenerator::finishCreation):

  • runtime/JSGenerator.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::asyncGeneratorStructure const):

  • runtime/JSType.cpp:

(WTF::printInternal):

  • runtime/JSType.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r250025 r250630  
    3333#include "CallFrame.h"
    3434#include "JIT.h"
     35#include "JSAsyncGenerator.h"
    3536#include "JSCInlines.h"
    3637#include "JSFunction.h"
     
    10351036}
    10361037
     1038static JSAsyncGenerator::Field asyncGeneratorInternalFieldIndex(BytecodeIntrinsicNode* node)
     1039{
     1040    if (node->emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldState)
     1041        return JSAsyncGenerator::Field::State;
     1042    if (node->emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldNext)
     1043        return JSAsyncGenerator::Field::Next;
     1044    if (node->emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldThis)
     1045        return JSAsyncGenerator::Field::This;
     1046    if (node->emitter() == &BytecodeIntrinsicNode::emit_intrinsic_generatorFieldFrame)
     1047        return JSAsyncGenerator::Field::Frame;
     1048    if (node->emitter() == &BytecodeIntrinsicNode::emit_intrinsic_asyncGeneratorFieldSuspendReason)
     1049        return JSAsyncGenerator::Field::SuspendReason;
     1050    if (node->emitter() == &BytecodeIntrinsicNode::emit_intrinsic_asyncGeneratorFieldQueueFirst)
     1051        return JSAsyncGenerator::Field::QueueFirst;
     1052    if (node->emitter() == &BytecodeIntrinsicNode::emit_intrinsic_asyncGeneratorFieldQueueLast)
     1053        return JSAsyncGenerator::Field::QueueLast;
     1054    RELEASE_ASSERT_NOT_REACHED();
     1055    return JSAsyncGenerator::Field::State;
     1056}
     1057
    10371058RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getPromiseInternalField(BytecodeGenerator& generator, RegisterID* dst)
    10381059{
     
    10561077    unsigned index = static_cast<unsigned>(generatorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
    10571078    ASSERT(index < JSGenerator::numberOfInternalFields);
     1079    ASSERT(!node->m_next);
     1080
     1081    return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
     1082}
     1083
     1084RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getAsyncGeneratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
     1085{
     1086    ArgumentListNode* node = m_args->m_listNode;
     1087    RefPtr<RegisterID> base = generator.emitNode(node);
     1088    node = node->m_next;
     1089    RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
     1090    unsigned index = static_cast<unsigned>(asyncGeneratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
     1091    ASSERT(index < JSAsyncGenerator::numberOfInternalFields);
    10581092    ASSERT(!node->m_next);
    10591093
     
    11541188    unsigned index = static_cast<unsigned>(generatorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
    11551189    ASSERT(index < JSGenerator::numberOfInternalFields);
     1190    node = node->m_next;
     1191    RefPtr<RegisterID> value = generator.emitNode(node);
     1192
     1193    ASSERT(!node->m_next);
     1194
     1195    return generator.move(dst, generator.emitPutInternalField(base.get(), index, value.get()));
     1196}
     1197
     1198RegisterID* BytecodeIntrinsicNode::emit_intrinsic_putAsyncGeneratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
     1199{
     1200    ArgumentListNode* node = m_args->m_listNode;
     1201    RefPtr<RegisterID> base = generator.emitNode(node);
     1202    node = node->m_next;
     1203    RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
     1204    unsigned index = static_cast<unsigned>(asyncGeneratorInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
     1205    ASSERT(index < JSAsyncGenerator::numberOfInternalFields);
    11561206    node = node->m_next;
    11571207    RefPtr<RegisterID> value = generator.emitNode(node);
     
    12841334    return generator.move(dst, generator.emitIsGenerator(generator.tempDestination(dst), src.get()));
    12851335}
    1286    
     1336
     1337RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isAsyncGenerator(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
     1338{
     1339    ArgumentListNode* node = m_args->m_listNode;
     1340    RefPtr<RegisterID> src = generator.emitNode(node);
     1341    ASSERT(!node->m_next);
     1342
     1343    return generator.move(dst, generator.emitIsAsyncGenerator(generator.tempDestination(dst), src.get()));
     1344}
     1345
    12871346RegisterID* BytecodeIntrinsicNode::emit_intrinsic_isJSArray(JSC::BytecodeGenerator& generator, JSC::RegisterID* dst)
    12881347{
     
    41594218        } else
    41604219            arg = generator.emitLoad(nullptr, jsUndefined());
    4161         RefPtr<RegisterID> value = generator.emitYield(arg.get(), JSAsyncGeneratorFunction::AsyncGeneratorSuspendReason::Yield);
     4220        RefPtr<RegisterID> value = generator.emitYield(arg.get(), JSAsyncGenerator::AsyncGeneratorSuspendReason::Yield);
    41624221        if (dst == generator.ignoredResult())
    41634222            return nullptr;
     
    41784237    RefPtr<RegisterID> arg = generator.newTemporary();
    41794238    generator.emitNode(arg.get(), argument());
    4180     RefPtr<RegisterID> value = generator.emitYield(arg.get(), JSAsyncGeneratorFunction::AsyncGeneratorSuspendReason::Await);
     4239    RefPtr<RegisterID> value = generator.emitYield(arg.get(), JSAsyncGenerator::AsyncGeneratorSuspendReason::Await);
    41814240    if (dst == generator.ignoredResult())
    41824241        return nullptr;
Note: See TracChangeset for help on using the changeset viewer.