Changeset 222425 in webkit
- Timestamp:
- Sep 23, 2017, 8:05:53 AM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r222424 r222425 1 2017-09-23 Oleksandr Skachkov <gskachkov@gmail.com> 2 3 [ESNext] Async iteration - Implement Async Generator - optimization 4 https://bugs.webkit.org/show_bug.cgi?id=175891 5 6 Reviewed by Yusuke Suzuki. 7 8 Add small optimization for async generators: 9 1. merging async generator queue to async generator itself 10 generator.@first / generator.@last is enough, by doing so, 11 we remove one unnecessary object alloc. 12 2. merging request with queue. 13 14 * builtins/AsyncGeneratorPrototype.js: 15 (globalPrivate.asyncGeneratorQueueIsEmpty): 16 (globalPrivate.asyncGeneratorQueueCreateItem): 17 (globalPrivate.asyncGeneratorQueueEnqueue): 18 (globalPrivate.asyncGeneratorQueueDequeue): 19 (globalPrivate.asyncGeneratorDequeue): 20 (globalPrivate.isSuspendYieldState): 21 (globalPrivate.asyncGeneratorEnqueue): 22 * builtins/BuiltinNames.h: 23 * bytecompiler/BytecodeGenerator.cpp: 24 (JSC::BytecodeGenerator::emitPutAsyncGeneratorFields): 25 * bytecompiler/BytecodeGenerator.h: 26 * bytecompiler/NodesCodegen.cpp: 27 (JSC::FunctionNode::emitBytecode): 28 1 29 2017-09-23 Joseph Pecoraro <pecoraro@apple.com> 2 30 -
trunk/Source/JavaScriptCore/builtins/AsyncGeneratorPrototype.js
r221080 r222425 25 25 26 26 @globalPrivate 27 function createAsyncGeneratorQueue() 28 { 29 "use strict"; 30 31 return { first: null, last: null }; 32 } 33 34 @globalPrivate 35 function asyncGeneratorQueueIsEmpty(queue) 36 { 37 "use strict"; 38 39 return queue.last === null; 40 } 41 42 @globalPrivate 43 function asyncGeneratorQueueCreateItem(value, previous) 44 { 45 "use strict"; 46 47 return { value, previous, next: null }; 48 } 49 50 @globalPrivate 51 function asyncGeneratorQueueEnqueue(queue, value) 52 { 53 "use strict"; 54 55 if (queue.first === null && queue.last === null) { 56 queue.first = @asyncGeneratorQueueCreateItem(value, null); 57 queue.last = queue.first; 27 function asyncGeneratorQueueIsEmpty(generator) 28 { 29 "use strict"; 30 31 return generator.@asyncGeneratorQueueLast === null; 32 } 33 34 @globalPrivate 35 function asyncGeneratorQueueEnqueue(generator, item) 36 { 37 "use strict"; 38 39 @assert(item.@asyncGeneratorQueueItemNext === null && item.@asyncGeneratorQueueItemPrevious === null); 40 41 if (generator.@asyncGeneratorQueueFirst === null) { 42 @assert(generator.@asyncGeneratorQueueLast === null); 43 44 generator.@asyncGeneratorQueueFirst = item; 45 generator.@asyncGeneratorQueueLast = item; 58 46 } else { 59 const item = @asyncGeneratorQueueCreateItem(value, queue.last); 60 61 queue.last.next = item; 62 queue.last = item; 63 } 64 65 } 66 67 @globalPrivate 68 function asyncGeneratorQueueDequeue(queue) 69 { 70 "use strict"; 71 72 if (queue.first === null) 47 item.@asyncGeneratorQueueItemPrevious = generator.@asyncGeneratorQueueLast; 48 generator.@asyncGeneratorQueueLast.@asyncGeneratorQueueItemNext = item; 49 generator.@asyncGeneratorQueueLast = item; 50 } 51 } 52 53 @globalPrivate 54 function asyncGeneratorQueueDequeue(generator) 55 { 56 "use strict"; 57 58 if (generator.@asyncGeneratorQueueFirst === null) 73 59 return null; 74 60 75 const result = queue.first; 76 queue.first = result.next; 77 78 if (queue.first === null) 79 queue.last = null; 80 81 return result.value; 82 } 83 84 85 @globalPrivate 86 function asyncGeneratorQueueGetFirstValue(queue) 87 { 88 "use strict"; 89 90 return queue.first !== null ? queue.first.value : @undefined; 61 const result = generator.@asyncGeneratorQueueFirst; 62 generator.@asyncGeneratorQueueFirst = result.@asyncGeneratorQueueItemNext; 63 64 if (generator.@asyncGeneratorQueueFirst === null) 65 generator.@asyncGeneratorQueueLast = null; 66 67 return result; 91 68 } 92 69 … … 98 75 const queue = generator.@asyncGeneratorQueue; 99 76 100 @assert( queue !== @undefined && !@asyncGeneratorQueueIsEmpty(queue), "Async genetator's Queue is an empty List.");77 @assert(!@asyncGeneratorQueueIsEmpty(generator), "Async genetator's Queue is an empty List."); 101 78 102 return @asyncGeneratorQueueDequeue( queue);79 return @asyncGeneratorQueueDequeue(generator); 103 80 } 104 81 … … 119 96 120 97 return (generator.@generatorState > 0 && generator.@asyncGeneratorSuspendReason === @AsyncGeneratorSuspendReasonYield) 121 98 || generator.@generatorState === @AsyncGeneratorStateSuspendedYield; 122 99 } 123 100 … … 236 213 return @undefined; 237 214 238 const queue = generator.@asyncGeneratorQueue; 239 240 if (@asyncGeneratorQueueIsEmpty(queue)) 215 if (@asyncGeneratorQueueIsEmpty(generator)) 241 216 return @undefined; 242 217 243 const next = @asyncGeneratorQueueGetFirstValue(queue);218 const next = generator.@asyncGeneratorQueueFirst; 244 219 245 220 if (next.resumeMode !== @GeneratorResumeModeNormal) { … … 290 265 } 291 266 292 @asyncGeneratorQueueEnqueue(generator .@asyncGeneratorQueue, {resumeMode, value, promiseCapability});267 @asyncGeneratorQueueEnqueue(generator, {resumeMode, value, promiseCapability, @asyncGeneratorQueueItemNext: null, @asyncGeneratorQueueItemPrevious: null}); 293 268 294 269 if (!@isExecutionState(generator)) -
trunk/Source/JavaScriptCore/builtins/BuiltinNames.h
r221417 r222425 127 127 macro(asyncGeneratorSuspendReason) \ 128 128 macro(asyncGeneratorQueue) \ 129 macro(asyncGeneratorQueueFirst) \ 130 macro(asyncGeneratorQueueLast) \ 131 macro(asyncGeneratorQueueItemNext) \ 132 macro(asyncGeneratorQueueItemPrevious) \ 129 133 macro(promiseCapability) \ 130 134 macro(generatorResumeMode) \ -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r222421 r222425 2872 2872 } 2873 2873 2874 RegisterID* BytecodeGenerator::emitCreateAsyncGeneratorQueue(const JSTextPosition& divot) 2875 { 2876 auto varCreateAsyncGeneratorQueue = variable(propertyNames().builtinNames().createAsyncGeneratorQueuePrivateName()); 2877 RefPtr<RegisterID> scope = newTemporary(); 2878 RefPtr<RegisterID> queue = newTemporary(); 2879 moveToDestinationIfNeeded(scope.get(), emitResolveScope(scope.get(), varCreateAsyncGeneratorQueue)); 2880 RefPtr<RegisterID> createAsyncGeneratorQueue = emitGetFromScope(newTemporary(), scope.get(), varCreateAsyncGeneratorQueue, ThrowIfNotFound); 2881 2882 CallArguments args(*this, nullptr, 0); 2883 emitLoad(args.thisRegister(), jsUndefined()); 2884 2885 emitCall(queue.get(), createAsyncGeneratorQueue.get(), NoExpectedFunction, args, divot, divot, divot, DebuggableCall::No); 2886 2887 return queue.get(); 2888 } 2889 2890 void BytecodeGenerator::emitPutAsyncGeneratorFields(RegisterID* nextFunction, const JSTextPosition& divot) 2874 void BytecodeGenerator::emitPutAsyncGeneratorFields(RegisterID* nextFunction) 2891 2875 { 2892 2876 ASSERT(isAsyncGeneratorFunctionParseMode(parseMode())); … … 2902 2886 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().asyncGeneratorSuspendReasonPrivateName(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSAsyncGeneratorFunction::AsyncGeneratorSuspendReason::None))), PropertyNode::KnownDirect); 2903 2887 2904 2905 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().asyncGeneratorQueue PrivateName(), emitCreateAsyncGeneratorQueue(divot), PropertyNode::KnownDirect);2888 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().asyncGeneratorQueueFirstPrivateName(), emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect); 2889 emitDirectPutById(m_generatorRegister, propertyNames().builtinNames().asyncGeneratorQueueLastPrivateName(), emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect); 2906 2890 } 2907 2891 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r222421 r222425 608 608 private: 609 609 void emitTypeProfilerExpressionInfo(const JSTextPosition& startDivot, const JSTextPosition& endDivot); 610 RegisterID* emitCreateAsyncGeneratorQueue(const JSTextPosition&);611 610 public: 612 611 … … 705 704 void emitPutGeneratorFields(RegisterID* nextFunction); 706 705 707 void emitPutAsyncGeneratorFields(RegisterID* nextFunction , const JSTextPosition&);706 void emitPutAsyncGeneratorFields(RegisterID* nextFunction); 708 707 709 708 ExpectedFunction expectedFunctionForIdentifier(const Identifier&); -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r222421 r222425 3603 3603 else { 3604 3604 ASSERT(isAsyncGeneratorFunctionParseMode(generator.parseMode())); 3605 generator.emitPutAsyncGeneratorFields(next.get() , JSTextPosition(startLine(), startStartOffset(), startLineStartOffset()));3605 generator.emitPutAsyncGeneratorFields(next.get()); 3606 3606 } 3607 3607
Note:
See TracChangeset
for help on using the changeset viewer.