mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
3x faster Buffer.isBuffer
This commit is contained in:
@@ -1,6 +1,22 @@
|
||||
import { bench, run } from "mitata";
|
||||
|
||||
const N = parseInt(process.argv.slice(2).at(0) || "10", 10);
|
||||
var isBuffer = new Buffer(0);
|
||||
var isNOtBuffer = "not a buffer";
|
||||
|
||||
bench("Buffer.isBuffer(buffer)", () => {
|
||||
return Buffer.isBuffer(isBuffer);
|
||||
});
|
||||
|
||||
{
|
||||
var j = 0;
|
||||
j += 1;
|
||||
j += eval("'ok'");
|
||||
|
||||
bench("Buffer.isBuffer(string)", () => {
|
||||
return Buffer.isBuffer(j);
|
||||
});
|
||||
}
|
||||
|
||||
bench("Buffer.from('short string')", () => {
|
||||
return Buffer.from("short string");
|
||||
@@ -45,4 +61,4 @@ bench("Buffer.alloc(24_000)", () => {
|
||||
return Buffer.alloc(24_000);
|
||||
});
|
||||
|
||||
await run();
|
||||
await run({});
|
||||
|
||||
@@ -115,18 +115,6 @@ static JSUint8Array* allocBufferUnsafe(JSC::JSGlobalObject* lexicalGlobalObject,
|
||||
return uint8Array;
|
||||
}
|
||||
|
||||
bool JSBuffer__isBuffer(JSC::JSGlobalObject* lexicalGlobalObject, JSC::EncodedJSValue value)
|
||||
{
|
||||
JSC::VM& vm = lexicalGlobalObject->vm();
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
|
||||
auto* jsBuffer = JSC::jsDynamicCast<JSC::JSUint8Array*>(JSC::JSValue::decode(value));
|
||||
if (!jsBuffer)
|
||||
return false;
|
||||
|
||||
return jsBuffer->hasProperty(lexicalGlobalObject, clientData->builtinNames().dataViewPrivateName());
|
||||
}
|
||||
|
||||
// Normalize val to be an integer in the range of [1, -1] since
|
||||
// implementations of memcmp() can vary by platform.
|
||||
static int normalizeCompareVal(int val, size_t a_length, size_t b_length)
|
||||
@@ -378,8 +366,8 @@ static inline JSC::EncodedJSValue jsBufferConstructorFunction_allocBody(JSC::JSG
|
||||
auto* subclassStructure = globalObject->JSBufferSubclassStructure();
|
||||
|
||||
// fill argument
|
||||
if (callFrame->argumentCount() > 1) {
|
||||
auto uint8Array = JSC::JSUint8Array::createUninitialized(lexicalGlobalObject, subclassStructure, length);
|
||||
if (UNLIKELY(callFrame->argumentCount() > 1)) {
|
||||
auto* uint8Array = JSC::JSUint8Array::createUninitialized(lexicalGlobalObject, subclassStructure, length);
|
||||
|
||||
auto value = callFrame->argument(1);
|
||||
|
||||
@@ -422,12 +410,12 @@ static inline JSC::EncodedJSValue jsBufferConstructorFunction_allocBody(JSC::JSG
|
||||
RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(uint8Array));
|
||||
}
|
||||
} else {
|
||||
auto arrayBuffer = JSC::ArrayBuffer::tryCreate(length, 1);
|
||||
if (!arrayBuffer) {
|
||||
auto* uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, length);
|
||||
if (UNLIKELY(!uint8Array)) {
|
||||
throwOutOfMemoryError(lexicalGlobalObject, throwScope);
|
||||
return JSValue::encode(jsUndefined());
|
||||
return JSC::JSValue::encode(jsUndefined());
|
||||
}
|
||||
auto uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, WTFMove(arrayBuffer), 0, length);
|
||||
|
||||
RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(uint8Array));
|
||||
}
|
||||
}
|
||||
@@ -1559,6 +1547,24 @@ JSC_DEFINE_HOST_FUNCTION(jsBufferConstructorFunction_concat, (JSGlobalObject * l
|
||||
extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(jsBufferConstructorAllocWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int size));
|
||||
extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(jsBufferConstructorAllocUnsafeWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int size));
|
||||
extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(jsBufferConstructorAllocUnsafeSlowWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int size));
|
||||
extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(jsBufferConstructorIsBufferWithoutTypeChecks, JSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void*, JSUint8Array* value));
|
||||
|
||||
static bool isBufferWithCell(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSUint8Array* cell)
|
||||
{
|
||||
auto& vm = lexicalGlobalObject->vm();
|
||||
JSValue prototype = cell->getPrototype(vm, lexicalGlobalObject);
|
||||
return prototype.inherits<JSBufferPrototype>();
|
||||
}
|
||||
|
||||
JSC_DEFINE_JIT_OPERATION(jsBufferConstructorIsBufferWithoutTypeChecks, JSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* ctx, JSUint8Array* thisValue))
|
||||
{
|
||||
VM& vm = JSC::getVM(lexicalGlobalObject);
|
||||
IGNORE_WARNINGS_BEGIN("frame-address")
|
||||
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
|
||||
IGNORE_WARNINGS_END
|
||||
JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
|
||||
return jsBoolean(isBufferWithCell(lexicalGlobalObject, thisValue));
|
||||
}
|
||||
|
||||
JSC_DEFINE_JIT_OPERATION(jsBufferConstructorAllocWithoutTypeChecks, JSUint8Array*, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, int byteLength))
|
||||
{
|
||||
@@ -1763,7 +1769,6 @@ void JSBufferPrototype::finishCreation(VM& vm, JSC::JSGlobalObject* globalThis)
|
||||
Base::finishCreation(vm);
|
||||
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
this->putDirect(vm, clientData->builtinNames().dataViewPrivateName(), JSC::jsUndefined(), JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
|
||||
reifyStaticProperties(vm, JSBuffer::info(), JSBufferPrototypeTableValues, *this);
|
||||
}
|
||||
|
||||
@@ -1781,6 +1786,11 @@ static const JSC::DOMJIT::Signature DOMJITSignaturejsBufferConstructorAlloc(jsBu
|
||||
JSC::DOMJIT::Effect::forWriteKinds(JSC::DFG::AbstractHeapKind::Heap),
|
||||
JSC::SpecUint8Array, JSC::SpecInt32Only);
|
||||
|
||||
static const JSC::DOMJIT::Signature DOMJITSignaturejsBufferConstructorIsBuffer(jsBufferConstructorIsBufferWithoutTypeChecks,
|
||||
JSBufferConstructor::info(),
|
||||
JSC::DOMJIT::Effect::forPure(),
|
||||
JSC::SpecOther, JSC::SpecUint8Array);
|
||||
|
||||
static const JSC::DOMJIT::Signature DOMJITSignaturejsBufferConstructorAllocUnsafe(jsBufferConstructorAllocUnsafeWithoutTypeChecks,
|
||||
JSBufferConstructor::info(),
|
||||
JSC::DOMJIT::Effect::forWriteKinds(JSC::DFG::AbstractHeapKind::Heap),
|
||||
@@ -1802,7 +1812,7 @@ static const HashTableValue JSBufferConstructorTableValues[] = {
|
||||
{ "compare"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_compare, 2 } },
|
||||
{ "concat"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_concat, 2 } },
|
||||
{ "from"_s, static_cast<unsigned>(JSC::PropertyAttribute::Builtin), NoIntrinsic, { HashTableValue::BuiltinGeneratorType, jsBufferConstructorFromCodeGenerator, 1 } },
|
||||
{ "isBuffer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_isBuffer, 1 } },
|
||||
{ "isBuffer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction), NoIntrinsic, { HashTableValue::DOMJITFunctionType, jsBufferConstructorFunction_isBuffer, &DOMJITSignaturejsBufferConstructorIsBuffer } },
|
||||
{ "toBuffer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_toBuffer, 1 } },
|
||||
{ "isEncoding"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_isEncoding, 1 } },
|
||||
};
|
||||
@@ -1976,3 +1986,20 @@ JSC_DEFINE_HOST_FUNCTION(constructJSBuffer, (JSC::JSGlobalObject * lexicalGlobal
|
||||
|
||||
RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(object));
|
||||
}
|
||||
|
||||
bool JSBuffer__isBuffer(JSC::JSGlobalObject* lexicalGlobalObject, JSC::EncodedJSValue value)
|
||||
{
|
||||
JSC::VM& vm = lexicalGlobalObject->vm();
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
|
||||
JSC::JSValue jsValue = JSC::JSValue::decode(value);
|
||||
if (!jsValue || !jsValue.isCell())
|
||||
return false;
|
||||
|
||||
JSC::JSUint8Array* cell = jsDynamicCast<JSC::JSUint8Array*>(jsValue.asCell());
|
||||
if (!cell)
|
||||
return false;
|
||||
|
||||
JSValue prototype = cell->getPrototype(vm, lexicalGlobalObject);
|
||||
return prototype.inherits<JSBufferPrototype>();
|
||||
}
|
||||
Reference in New Issue
Block a user