Skip to content

Commit

Permalink
Make creating errors slightly faster (oven-sh#16023)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarred-Sumner authored and probably-neb committed Jan 7, 2025
1 parent 0a00dbb commit f2893e8
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 17 deletions.
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);
});

0 comments on commit f2893e8

Please sign in to comment.