Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make creating errors slightly faster #16023

Merged
merged 5 commits into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmake/tools/SetupWebKit.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use")
option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading")

if(NOT WEBKIT_VERSION)
set(WEBKIT_VERSION 3845bf370ff4e9a5c0b96036255142c7904be963)
set(WEBKIT_VERSION 00e2b186fd25e79cea4cb4d63d9fd388192327f6)
endif()

if(WEBKIT_LOCAL)
Expand Down
8 changes: 8 additions & 0 deletions src/bun.js/bindings/BunCommonStrings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,25 @@ using namespace JSC;
init.set(jsOwnedString(init.vm, name.string())); \
});

#define BUN_COMMON_STRINGS_LAZY_PROPERTY_DEFINITION_NOT_BUILTIN_NAMES(jsName) \
this->m_commonString_##jsName.initLater( \
[](const JSC::LazyProperty<JSGlobalObject, JSString>::Initializer& init) { \
init.set(jsOwnedString(init.vm, #jsName##_s)); \
});

#define BUN_COMMON_STRINGS_LAZY_PROPERTY_VISITOR(name) this->m_commonString_##name.visit(visitor);

void CommonStrings::initialize()
{
BUN_COMMON_STRINGS_EACH_NAME(BUN_COMMON_STRINGS_LAZY_PROPERTY_DEFINITION)
BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(BUN_COMMON_STRINGS_LAZY_PROPERTY_DEFINITION_NOT_BUILTIN_NAMES)
}

template<typename Visitor>
void CommonStrings::visit(Visitor& visitor)
{
BUN_COMMON_STRINGS_EACH_NAME(BUN_COMMON_STRINGS_LAZY_PROPERTY_VISITOR)
BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(BUN_COMMON_STRINGS_LAZY_PROPERTY_VISITOR)
}

template void CommonStrings::visit(JSC::AbstractSlotVisitor&);
Expand Down
10 changes: 9 additions & 1 deletion src/bun.js/bindings/BunCommonStrings.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
#pragma once

// clang-format off
// The items in this list must also be present in BunBuiltinNames.h
// If we use it as an identifier name in hot code, we should put it in this list.
#define BUN_COMMON_STRINGS_EACH_NAME(macro) \
macro(require) \
macro(resolve) \
macro(mockedFunction)

// These ones don't need to be in BunBuiltinNames.h
// If we don't use it as an identifier name, but we want to avoid allocating the string frequently, put it in this list.
#define BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(macro) \
macro(SystemError)
// clang-format on

#define BUN_COMMON_STRINGS_ACCESSOR_DEFINITION(name) \
Expand All @@ -21,14 +28,15 @@ namespace Bun {
class CommonStrings {
public:
BUN_COMMON_STRINGS_EACH_NAME(BUN_COMMON_STRINGS_ACCESSOR_DEFINITION)

BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(BUN_COMMON_STRINGS_ACCESSOR_DEFINITION)
void initialize();

template<typename Visitor>
void visit(Visitor& visitor);

private:
BUN_COMMON_STRINGS_EACH_NAME(BUN_COMMON_STRINGS_LAZY_PROPERTY_DECLARATION)
BUN_COMMON_STRINGS_EACH_NAME_NOT_BUILTIN_NAMES(BUN_COMMON_STRINGS_LAZY_PROPERTY_DECLARATION)
};

} // namespace Bun
Expand Down
16 changes: 12 additions & 4 deletions src/bun.js/bindings/BunProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2565,10 +2565,18 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionMemoryUsage,

result->putDirectOffset(vm, 3, JSC::jsDoubleNumber(vm.heap.extraMemorySize() + vm.heap.externalMemorySize()));

// We report 0 for this because m_arrayBuffers in JSC::Heap is private and we need to add a binding
// If we use objectTypeCounts(), it's hideously slow because it loops through every single object in the heap
// TODO: add a binding for m_arrayBuffers, registerWrapper() in TypedArrayController doesn't work
result->putDirectOffset(vm, 4, JSC::jsNumber(0));
// JSC won't count this number until vm.heap.addReference() is called.
// That will only happen in cases like:
// - new ArrayBuffer()
// - new Uint8Array(42).buffer
// - fs.readFile(path, "utf-8") (sometimes)
// - ...
//
// But it won't happen in cases like:
// - new Uint8Array(42)
// - Buffer.alloc(42)
// - new Uint8Array(42).slice()
result->putDirectOffset(vm, 4, JSC::jsDoubleNumber(vm.heap.arrayBufferSize()));

RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(result));
}
Expand Down
22 changes: 12 additions & 10 deletions src/bun.js/bindings/bindings.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@


#include "root.h"

#include "JavaScriptCore/ErrorType.h"
#include "JavaScriptCore/CatchScope.h"
#include "JavaScriptCore/Exception.h"
#include "ErrorCode+List.h"
Expand Down Expand Up @@ -1941,45 +1943,45 @@ JSC__JSValue SystemError__toErrorInstance(const SystemError* arg0,
message = Bun::toJS(globalObject, err.message);
}

auto& names = WebCore::builtinNames(vm);

JSC::JSValue options = JSC::jsUndefined();

JSC::JSObject* result
= JSC::ErrorInstance::create(globalObject, JSC::ErrorInstance::createStructure(vm, globalObject, globalObject->errorPrototype()), message, options);

auto clientData = WebCore::clientData(vm);
JSC::JSObject* result = JSC::ErrorInstance::create(globalObject, globalObject->errorStructureWithErrorType<JSC::ErrorType::Error>(), message, options);

if (err.code.tag != BunStringTag::Empty) {
JSC::JSValue code = Bun::toJS(globalObject, err.code);
result->putDirect(vm, clientData->builtinNames().codePublicName(), code,
result->putDirect(vm, names.codePublicName(), code,
JSC::PropertyAttribute::DontDelete | 0);

result->putDirect(vm, vm.propertyNames->name, code, JSC::PropertyAttribute::DontEnum | 0);
} else {
auto* domGlobalObject = defaultGlobalObject(globalObject);
result->putDirect(
vm, vm.propertyNames->name,
JSC::JSValue(jsString(vm, String("SystemError"_s))),
JSC::JSValue(domGlobalObject->commonStrings().SystemErrorString(domGlobalObject)),
JSC::PropertyAttribute::DontEnum | 0);
}

if (err.path.tag != BunStringTag::Empty) {
JSC::JSValue path = Bun::toJS(globalObject, err.path);
result->putDirect(vm, clientData->builtinNames().pathPublicName(), path,
result->putDirect(vm, names.pathPublicName(), path,
JSC::PropertyAttribute::DontDelete | 0);
}

if (err.fd != -1) {
JSC::JSValue fd = JSC::JSValue(jsNumber(err.fd));
result->putDirect(vm, JSC::Identifier::fromString(vm, "fd"_s), fd,
result->putDirect(vm, names.fdPublicName(), fd,
JSC::PropertyAttribute::DontDelete | 0);
}

if (err.syscall.tag != BunStringTag::Empty) {
JSC::JSValue syscall = Bun::toJS(globalObject, err.syscall);
result->putDirect(vm, clientData->builtinNames().syscallPublicName(), syscall,
result->putDirect(vm, names.syscallPublicName(), syscall,
JSC::PropertyAttribute::DontDelete | 0);
}

result->putDirect(vm, clientData->builtinNames().errnoPublicName(), JSC::JSValue(err.errno_),
result->putDirect(vm, names.errnoPublicName(), JSC::JSValue(err.errno_),
JSC::PropertyAttribute::DontDelete | 0);

RETURN_IF_EXCEPTION(scope, {});
Expand Down
22 changes: 21 additions & 1 deletion src/bun.js/modules/BunJSCModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,24 @@ JSC_DEFINE_HOST_FUNCTION(functionEstimateDirectMemoryUsageOf, (JSGlobalObject *
return JSValue::encode(jsNumber(0));
}

#if USE(BMALLOC_MEMORY_FOOTPRINT_API)

#include <bmalloc/bmalloc.h>

JSC_DEFINE_HOST_FUNCTION(functionPercentAvailableMemoryInUse, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
return JSValue::encode(jsDoubleNumber(bmalloc::api::percentAvailableMemoryInUse()));
}

#else

JSC_DEFINE_HOST_FUNCTION(functionPercentAvailableMemoryInUse, (JSGlobalObject * globalObject, CallFrame* callFrame))
{
return JSValue::encode(jsNull());
}

#endif

// clang-format off
/* Source for BunJSCModuleTable.lut.h
@begin BunJSCModuleTable
Expand Down Expand Up @@ -937,13 +955,14 @@ JSC_DEFINE_HOST_FUNCTION(functionEstimateDirectMemoryUsageOf, (JSGlobalObject *
serialize functionSerialize Function 0
deserialize functionDeserialize Function 0
estimateShallowMemoryUsageOf functionEstimateDirectMemoryUsageOf Function 1
percentAvailableMemoryInUse functionPercentAvailableMemoryInUse Function 0
@end
*/

namespace Zig {
DEFINE_NATIVE_MODULE(BunJSC)
{
INIT_NATIVE_MODULE(35);
INIT_NATIVE_MODULE(36);

putNativeFn(Identifier::fromString(vm, "callerSourceOrigin"_s), functionCallerSourceOrigin);
putNativeFn(Identifier::fromString(vm, "jscDescribe"_s), functionDescribe);
Expand Down Expand Up @@ -977,6 +996,7 @@ DEFINE_NATIVE_MODULE(BunJSC)
putNativeFn(Identifier::fromString(vm, "serialize"_s), functionSerialize);
putNativeFn(Identifier::fromString(vm, "deserialize"_s), functionDeserialize);
putNativeFn(Identifier::fromString(vm, "estimateShallowMemoryUsageOf"_s), functionEstimateDirectMemoryUsageOf);
putNativeFn(Identifier::fromString(vm, "percentAvailableMemoryInUse"_s), functionPercentAvailableMemoryInUse);

// Deprecated
putNativeFn(Identifier::fromString(vm, "describe"_s), functionDescribe);
Expand Down
7 changes: 7 additions & 0 deletions test/js/node/process/process.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1056,3 +1056,10 @@ describe("process.exitCode", () => {
it("process._exiting", () => {
expect(process._exiting).toBe(false);
});

it("process.memoryUsage.arrayBuffers", () => {
const initial = process.memoryUsage().arrayBuffers;
const array = new ArrayBuffer(1024 * 1024 * 16);
array.buffer;
expect(process.memoryUsage().arrayBuffers).toBeGreaterThanOrEqual(initial + 16 * 1024 * 1024);
});
Loading