1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 21:57:35 +00:00

LibJS: Avoid lots of string-to-int during global object construction

We were doing a *lot* of string-to-int conversion while creating a new
global object. This happened because Object::put() would try to convert
the property name (string) to an integer to see if it refers to an
indexed property.

Sidestep this issue by using PropertyName for the CommonPropertyNames
struct on VM (vm.names.foo), and giving PropertyName a flag that tells
us whether it's a string that *may be* a number.

All CommonPropertyNames are set up so they are known to not be numbers.
This commit is contained in:
Andreas Kling 2021-06-13 18:59:07 +02:00
parent 53a8a11973
commit 5eef07d232
25 changed files with 84 additions and 58 deletions

View file

@ -13,13 +13,18 @@ namespace JS {
class PropertyName {
public:
enum class Type {
enum class Type : u8 {
Invalid,
Number,
String,
Symbol,
};
enum class StringMayBeNumber {
Yes,
No,
};
static PropertyName from_value(GlobalObject& global_object, Value value)
{
if (value.is_empty())
@ -56,8 +61,9 @@ public:
VERIFY(!string.is_null());
}
PropertyName(FlyString const& string)
PropertyName(FlyString const& string, StringMayBeNumber string_may_be_number = StringMayBeNumber::Yes)
: m_type(Type::String)
, m_string_may_be_number(string_may_be_number == StringMayBeNumber::Yes)
, m_string(string)
{
VERIFY(!string.is_null());
@ -85,6 +91,7 @@ public:
bool is_number() const { return m_type == Type::Number; }
bool is_string() const { return m_type == Type::String; }
bool is_symbol() const { return m_type == Type::Symbol; }
bool string_may_be_number() const { return m_string_may_be_number; }
u32 as_number() const
{
@ -135,9 +142,22 @@ public:
private:
Type m_type { Type::Invalid };
bool m_string_may_be_number { true };
FlyString m_string;
Symbol* m_symbol { nullptr };
u32 m_number { 0 };
};
}
namespace AK {
template<>
struct Formatter<JS::PropertyName> : Formatter<StringView> {
void format(FormatBuilder& builder, JS::PropertyName const& value)
{
Formatter<StringView>::format(builder, value.to_string());
}
};
}