From 4eed310a459b09d167c85b166472eaaaea1e7db4 Mon Sep 17 00:00:00 2001 From: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> Date: Thu, 1 Dec 2022 18:51:16 -0800 Subject: 3x faster `TextEncoder.prototype.encodeInto` thanks to @Constellation for the tip --- src/bun.js/bindings/ZigGlobalObject.cpp | 22 +++++++++++++--------- src/bun.js/bindings/ZigGlobalObject.h | 4 ++-- src/bun.js/bindings/webcore/JSTextEncoder.cpp | 19 +++++++------------ 3 files changed, 22 insertions(+), 23 deletions(-) (limited to 'src/bun.js') diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 467498aae..bcb42dc29 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -2490,12 +2490,18 @@ void GlobalObject::finishCreation(VM& vm) init.set(map); }); - m_encodeIntoObjectPrototype.initLater( - [](const JSC::LazyProperty::Initializer& init) { - JSC::JSObject* object = JSC::constructEmptyObject(init.owner, init.owner->objectPrototype(), 2); - object->putDirect(init.vm, JSC::Identifier::fromString(init.vm, "read"_s), JSC::jsNumber(0), 0); - object->putDirect(init.vm, JSC::Identifier::fromString(init.vm, "written"_s), JSC::jsNumber(0), 0); - init.set(object); + m_encodeIntoObjectStructure.initLater( + [](const JSC::LazyProperty::Initializer& init) { + auto& vm = init.vm; + auto& globalObject = *init.owner; + Structure* structure = globalObject.structureCache().emptyObjectStructureForPrototype(&globalObject, globalObject.objectPrototype(), 2); + PropertyOffset offset; + auto clientData = WebCore::clientData(vm); + structure = Structure::addPropertyTransition(vm, structure, clientData->builtinNames().readPublicName(), 0, offset); + RELEASE_ASSERT(offset == 0); + structure = Structure::addPropertyTransition(vm, structure, clientData->builtinNames().writtenPublicName(), 0, offset); + RELEASE_ASSERT(offset == 1); + init.set(structure); }); m_JSFileSinkClassStructure.initLater( @@ -3337,7 +3343,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor) thisObject->m_performMicrotaskVariadicFunction.visit(visitor); thisObject->m_lazyReadableStreamPrototypeMap.visit(visitor); thisObject->m_requireMap.visit(visitor); - thisObject->m_encodeIntoObjectPrototype.visit(visitor); + thisObject->m_encodeIntoObjectStructure.visit(visitor); thisObject->m_JSArrayBufferControllerPrototype.visit(visitor); thisObject->m_JSFileSinkControllerPrototype.visit(visitor); thisObject->m_JSHTTPSResponseControllerPrototype.visit(visitor); @@ -3608,8 +3614,6 @@ JSC::JSValue GlobalObject::moduleLoaderEvaluate(JSGlobalObject* globalObject, return result; } - - #include "ZigGeneratedClasses+lazyStructureImpl.h" } // namespace Zig diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index b537bbb12..bcc6cb804 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -229,7 +229,7 @@ public: JSC::JSMap* readableStreamNativeMap() { return m_lazyReadableStreamPrototypeMap.getInitializedOnMainThread(this); } JSC::JSMap* requireMap() { return m_requireMap.getInitializedOnMainThread(this); } - JSC::JSObject* encodeIntoObjectPrototype() { return m_encodeIntoObjectPrototype.getInitializedOnMainThread(this); } + JSC::Structure* encodeIntoObjectStructure() { return m_encodeIntoObjectStructure.getInitializedOnMainThread(this); } JSC::Structure* callSiteStructure() const { return m_callSiteStructure.getInitializedOnMainThread(this); } @@ -483,7 +483,7 @@ private: LazyProperty m_emitReadableNextTickFunction; LazyProperty m_lazyReadableStreamPrototypeMap; LazyProperty m_requireMap; - LazyProperty m_encodeIntoObjectPrototype; + LazyProperty m_encodeIntoObjectStructure; LazyProperty m_JSArrayBufferControllerPrototype; LazyProperty m_JSFileSinkControllerPrototype; LazyProperty m_JSHTTPSResponseControllerPrototype; diff --git a/src/bun.js/bindings/webcore/JSTextEncoder.cpp b/src/bun.js/bindings/webcore/JSTextEncoder.cpp index 90092163f..09352b98f 100644 --- a/src/bun.js/bindings/webcore/JSTextEncoder.cpp +++ b/src/bun.js/bindings/webcore/JSTextEncoder.cpp @@ -296,11 +296,9 @@ JSC_DEFINE_JIT_OPERATION(jsTextEncoderPrototypeFunction_encodeIntoWithoutTypeChe } Zig::GlobalObject* globalObject = reinterpret_cast(lexicalGlobalObject); - auto clientData = WebCore::clientData(vm); - - auto* result = JSC::constructEmptyObject(globalObject, globalObject->encodeIntoObjectPrototype(), 2); - result->putDirect(vm, clientData->builtinNames().readPublicName(), JSC::jsNumber(static_cast(res)), 0); - result->putDirect(vm, clientData->builtinNames().writtenPublicName(), JSC::jsNumber(static_cast(res >> 32)), 0); + auto* result = JSC::constructEmptyObject(vm, globalObject->encodeIntoObjectStructure()); + result->putDirectOffset(vm, 0, JSC::jsNumber(static_cast(res))); + result->putDirectOffset(vm, 1, JSC::jsNumber(static_cast(res >> 32))); return JSValue::encode(result); } @@ -416,15 +414,13 @@ static inline JSC::EncodedJSValue jsTextEncoderPrototypeFunction_encodeIntoBody( { auto& vm = JSC::getVM(lexicalGlobalObject); auto throwScope = DECLARE_THROW_SCOPE(vm); - UNUSED_PARAM(throwScope); - UNUSED_PARAM(callFrame); if (UNLIKELY(callFrame->argumentCount() < 2)) return throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)); EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); auto source = argument0.value().toWTFString(lexicalGlobalObject); RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); - auto* destination = JSC::jsDynamicCast(argument1.value()); + auto* destination = JSC::jsDynamicCast(argument1.value()); if (!destination) { throwVMTypeError(lexicalGlobalObject, throwScope, "Expected Uint8Array"_s); return encodedJSValue(); @@ -438,11 +434,10 @@ static inline JSC::EncodedJSValue jsTextEncoderPrototypeFunction_encodeIntoBody( } Zig::GlobalObject* globalObject = reinterpret_cast(lexicalGlobalObject); - auto clientData = WebCore::clientData(vm); - auto* result = JSC::constructEmptyObject(globalObject, globalObject->encodeIntoObjectPrototype(), 2); - result->putDirect(vm, clientData->builtinNames().readPublicName(), JSC::jsNumber(static_cast(res)), 0); - result->putDirect(vm, clientData->builtinNames().writtenPublicName(), JSC::jsNumber(static_cast(res >> 32)), 0); + auto* result = JSC::constructEmptyObject(vm, globalObject->encodeIntoObjectStructure()); + result->putDirectOffset(vm, 0, JSC::jsNumber(static_cast(res))); + result->putDirectOffset(vm, 1, JSC::jsNumber(static_cast(res >> 32))); return JSValue::encode(result); } -- cgit v1.2.3