Ignore:
Timestamp:
Oct 14, 2020, 2:48:50 PM (5 years ago)
Author:
Alexey Shvayka
Message:

Use @putByValDirect instead of Array.prototype.@push in built-ins
https://bugs.webkit.org/show_bug.cgi?id=175432

Reviewed by Yusuke Suzuki.

JSTests:

  • stress/array-push-intrinsic.js: Added.
  • test262/expectations.yaml: Mark 2 test cases as passing.

Source/JavaScriptCore:

Before this patch, Array.prototype.@push was used to implement List spec type,
stacks / queues, and in place of CreateDataProperty [1].
It's undesirably observable since elements are pushed using Set,
affecting indexed properties on prototypes [2].

This change introduces @arrayPush() intrinsic to use with lists / stacks / queues.
@arrayPush() should only be used with JSArray receivers because "length" isn't
incremented. Unlike Array.prototype.@push, it doesn't grow arrays beyond UINT_MAX,
which is OK for current use cases. Object.entries microbenchmark is neutral.

Despite Array.prototype.@shift also performing Set, it's safe to use with
non-sparse receivers.

[1]: https://tc39.es/ecma262/#sec-createarrayfromlist (step 4.a)
[2]: https://tc39.es/ecma262/#sec-array.prototype.push (step 5.a)

  • builtins/ArrayPrototype.js:

(globalPrivate.sortBucketSort):

  • builtins/ObjectConstructor.js:

(entries):

  • builtins/RegExpPrototype.js:

(globalPrivate.matchSlow):
(Symbol.replace):
(Symbol.split):

  • builtins/TypedArrayPrototype.js:

(filter):

  • bytecode/BytecodeIntrinsicRegistry.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::BytecodeIntrinsicNode::emit_intrinsic_arrayPush):

  • runtime/ArrayPrototype.cpp:

(JSC::ArrayPrototype::finishCreation):

Source/WebCore:

Use @arrayPush() intrinsic instead of Array.prototype.@push.

No new tests, no behavior change.

  • Modules/streams/ReadableByteStreamInternals.js:

(readableByteStreamControllerPull):
(readableByteStreamControllerEnqueueChunk):
(readableByteStreamControllerPullInto):
(readableStreamAddReadIntoRequest):

  • Modules/streams/ReadableStreamInternals.js:

(readableStreamAddReadRequest):

  • Modules/streams/StreamInternals.js:

(enqueueValueWithSize):

  • Modules/streams/WritableStreamInternals.js:

(writableStreamAddWriteRequest):

File:
1 edited

Legend:

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

    r268374 r268489  
    13871387
    13881388    return generator.emitArgumentCount(generator.finalDestination(dst));
     1389}
     1390
     1391RegisterID* BytecodeIntrinsicNode::emit_intrinsic_arrayPush(BytecodeGenerator& generator, RegisterID* dst)
     1392{
     1393    ArgumentListNode* node = m_args->m_listNode;
     1394    RefPtr<RegisterID> base = generator.emitNode(node);
     1395    node = node->m_next;
     1396    RefPtr<RegisterID> value = generator.emitNode(node);
     1397
     1398    ASSERT(!node->m_next);
     1399
     1400    RefPtr<RegisterID> length = generator.emitDirectGetById(generator.newTemporary(), base.get(), generator.propertyNames().length);
     1401    return generator.move(dst, generator.emitDirectPutByVal(base.get(), length.get(), value.get()));
    13891402}
    13901403
Note: See TracChangeset for help on using the changeset viewer.