summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorGunnar Beutner <gbeutner@serenityos.org>2021-06-13 22:55:00 +0200
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-06-14 16:09:58 +0430
commitd3c2a3caea4aa999879898dc0031ff2224709da8 (patch)
tree7b81f556411771b98f504e4b834ae6745db6a38f /Userland/Libraries
parent794dc368f19b1c9bf7161def8a26e1282e78a925 (diff)
downloadserenity-d3c2a3caea4aa999879898dc0031ff2224709da8.zip
LibRegex: Avoid initialization checks in get_opcode_by_id()
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibRegex/RegexByteCode.cpp111
-rw-r--r--Userland/Libraries/LibRegex/RegexByteCode.h79
2 files changed, 65 insertions, 125 deletions
diff --git a/Userland/Libraries/LibRegex/RegexByteCode.cpp b/Userland/Libraries/LibRegex/RegexByteCode.cpp
index 2f51ddd8b0..8ffe33f265 100644
--- a/Userland/Libraries/LibRegex/RegexByteCode.cpp
+++ b/Userland/Libraries/LibRegex/RegexByteCode.cpp
@@ -90,64 +90,67 @@ static const char* character_class_name(CharClass ch_class)
OwnPtr<OpCode> ByteCode::s_opcodes[(size_t)OpCodeId::Last + 1];
bool ByteCode::s_opcodes_initialized { false };
-ALWAYS_INLINE OpCode& ByteCode::get_opcode_by_id(OpCodeId id) const
+void ByteCode::ensure_opcodes_initialized()
{
- if (!s_opcodes_initialized) {
- for (u32 i = (u32)OpCodeId::First; i <= (u32)OpCodeId::Last; ++i) {
- switch ((OpCodeId)i) {
- case OpCodeId::Exit:
- s_opcodes[i] = make<OpCode_Exit>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::Jump:
- s_opcodes[i] = make<OpCode_Jump>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::Compare:
- s_opcodes[i] = make<OpCode_Compare>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::CheckEnd:
- s_opcodes[i] = make<OpCode_CheckEnd>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::CheckBoundary:
- s_opcodes[i] = make<OpCode_CheckBoundary>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::ForkJump:
- s_opcodes[i] = make<OpCode_ForkJump>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::ForkStay:
- s_opcodes[i] = make<OpCode_ForkStay>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::FailForks:
- s_opcodes[i] = make<OpCode_FailForks>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::Save:
- s_opcodes[i] = make<OpCode_Save>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::Restore:
- s_opcodes[i] = make<OpCode_Restore>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::GoBack:
- s_opcodes[i] = make<OpCode_GoBack>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::CheckBegin:
- s_opcodes[i] = make<OpCode_CheckBegin>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::SaveLeftCaptureGroup:
- s_opcodes[i] = make<OpCode_SaveLeftCaptureGroup>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::SaveRightCaptureGroup:
- s_opcodes[i] = make<OpCode_SaveRightCaptureGroup>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::SaveLeftNamedCaptureGroup:
- s_opcodes[i] = make<OpCode_SaveLeftNamedCaptureGroup>(*const_cast<ByteCode*>(this));
- break;
- case OpCodeId::SaveRightNamedCaptureGroup:
- s_opcodes[i] = make<OpCode_SaveRightNamedCaptureGroup>(*const_cast<ByteCode*>(this));
- break;
- }
+ if (s_opcodes_initialized)
+ return;
+ for (u32 i = (u32)OpCodeId::First; i <= (u32)OpCodeId::Last; ++i) {
+ switch ((OpCodeId)i) {
+ case OpCodeId::Exit:
+ s_opcodes[i] = make<OpCode_Exit>();
+ break;
+ case OpCodeId::Jump:
+ s_opcodes[i] = make<OpCode_Jump>();
+ break;
+ case OpCodeId::Compare:
+ s_opcodes[i] = make<OpCode_Compare>();
+ break;
+ case OpCodeId::CheckEnd:
+ s_opcodes[i] = make<OpCode_CheckEnd>();
+ break;
+ case OpCodeId::CheckBoundary:
+ s_opcodes[i] = make<OpCode_CheckBoundary>();
+ break;
+ case OpCodeId::ForkJump:
+ s_opcodes[i] = make<OpCode_ForkJump>();
+ break;
+ case OpCodeId::ForkStay:
+ s_opcodes[i] = make<OpCode_ForkStay>();
+ break;
+ case OpCodeId::FailForks:
+ s_opcodes[i] = make<OpCode_FailForks>();
+ break;
+ case OpCodeId::Save:
+ s_opcodes[i] = make<OpCode_Save>();
+ break;
+ case OpCodeId::Restore:
+ s_opcodes[i] = make<OpCode_Restore>();
+ break;
+ case OpCodeId::GoBack:
+ s_opcodes[i] = make<OpCode_GoBack>();
+ break;
+ case OpCodeId::CheckBegin:
+ s_opcodes[i] = make<OpCode_CheckBegin>();
+ break;
+ case OpCodeId::SaveLeftCaptureGroup:
+ s_opcodes[i] = make<OpCode_SaveLeftCaptureGroup>();
+ break;
+ case OpCodeId::SaveRightCaptureGroup:
+ s_opcodes[i] = make<OpCode_SaveRightCaptureGroup>();
+ break;
+ case OpCodeId::SaveLeftNamedCaptureGroup:
+ s_opcodes[i] = make<OpCode_SaveLeftNamedCaptureGroup>();
+ break;
+ case OpCodeId::SaveRightNamedCaptureGroup:
+ s_opcodes[i] = make<OpCode_SaveRightNamedCaptureGroup>();
+ break;
}
- s_opcodes_initialized = true;
}
+ s_opcodes_initialized = true;
+}
+ALWAYS_INLINE OpCode& ByteCode::get_opcode_by_id(OpCodeId id) const
+{
VERIFY(id >= OpCodeId::First && id <= OpCodeId::Last);
auto& opcode = s_opcodes[(u32)id];
diff --git a/Userland/Libraries/LibRegex/RegexByteCode.h b/Userland/Libraries/LibRegex/RegexByteCode.h
index 7d4cb43007..7d78c1303c 100644
--- a/Userland/Libraries/LibRegex/RegexByteCode.h
+++ b/Userland/Libraries/LibRegex/RegexByteCode.h
@@ -129,7 +129,11 @@ class OpCode;
class ByteCode : public Vector<ByteCodeValueType> {
public:
- ByteCode() = default;
+ ByteCode()
+ {
+ ensure_opcodes_initialized();
+ }
+
ByteCode(const ByteCode&) = default;
virtual ~ByteCode() = default;
@@ -449,6 +453,7 @@ private:
empend((ByteCodeValueType)view[i]);
}
+ void ensure_opcodes_initialized();
ALWAYS_INLINE OpCode& get_opcode_by_id(OpCodeId id) const;
static OwnPtr<OpCode> s_opcodes[(size_t)OpCodeId::Last + 1];
static bool s_opcodes_initialized;
@@ -476,11 +481,7 @@ const char* execution_result_name(ExecutionResult result);
class OpCode {
public:
- OpCode(ByteCode& bytecode)
- : m_bytecode(&bytecode)
- {
- }
-
+ OpCode() = default;
virtual ~OpCode() = default;
virtual OpCodeId opcode_id() const = 0;
@@ -518,16 +519,12 @@ public:
ALWAYS_INLINE const ByteCode& bytecode() const { return *m_bytecode; }
protected:
- ByteCode* m_bytecode;
+ ByteCode* m_bytecode { nullptr };
Optional<MatchState*> m_state;
};
class OpCode_Exit final : public OpCode {
public:
- OpCode_Exit(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::Exit; }
ALWAYS_INLINE size_t size() const override { return 1; }
@@ -536,10 +533,6 @@ public:
class OpCode_FailForks final : public OpCode {
public:
- OpCode_FailForks(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::FailForks; }
ALWAYS_INLINE size_t size() const override { return 2; }
@@ -549,10 +542,6 @@ public:
class OpCode_Save final : public OpCode {
public:
- OpCode_Save(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::Save; }
ALWAYS_INLINE size_t size() const override { return 1; }
@@ -561,10 +550,6 @@ public:
class OpCode_Restore final : public OpCode {
public:
- OpCode_Restore(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::Restore; }
ALWAYS_INLINE size_t size() const override { return 1; }
@@ -573,10 +558,6 @@ public:
class OpCode_GoBack final : public OpCode {
public:
- OpCode_GoBack(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::GoBack; }
ALWAYS_INLINE size_t size() const override { return 2; }
@@ -586,10 +567,6 @@ public:
class OpCode_Jump final : public OpCode {
public:
- OpCode_Jump(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::Jump; }
ALWAYS_INLINE size_t size() const override { return 2; }
@@ -602,10 +579,6 @@ public:
class OpCode_ForkJump final : public OpCode {
public:
- OpCode_ForkJump(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::ForkJump; }
ALWAYS_INLINE size_t size() const override { return 2; }
@@ -618,10 +591,6 @@ public:
class OpCode_ForkStay final : public OpCode {
public:
- OpCode_ForkStay(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::ForkStay; }
ALWAYS_INLINE size_t size() const override { return 2; }
@@ -634,10 +603,6 @@ public:
class OpCode_CheckBegin final : public OpCode {
public:
- OpCode_CheckBegin(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::CheckBegin; }
ALWAYS_INLINE size_t size() const override { return 1; }
@@ -646,10 +611,6 @@ public:
class OpCode_CheckEnd final : public OpCode {
public:
- OpCode_CheckEnd(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::CheckEnd; }
ALWAYS_INLINE size_t size() const override { return 1; }
@@ -658,10 +619,6 @@ public:
class OpCode_CheckBoundary final : public OpCode {
public:
- OpCode_CheckBoundary(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::CheckBoundary; }
ALWAYS_INLINE size_t size() const override { return 2; }
@@ -672,10 +629,6 @@ public:
class OpCode_SaveLeftCaptureGroup final : public OpCode {
public:
- OpCode_SaveLeftCaptureGroup(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::SaveLeftCaptureGroup; }
ALWAYS_INLINE size_t size() const override { return 2; }
@@ -685,10 +638,6 @@ public:
class OpCode_SaveRightCaptureGroup final : public OpCode {
public:
- OpCode_SaveRightCaptureGroup(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::SaveRightCaptureGroup; }
ALWAYS_INLINE size_t size() const override { return 2; }
@@ -698,10 +647,6 @@ public:
class OpCode_SaveLeftNamedCaptureGroup final : public OpCode {
public:
- OpCode_SaveLeftNamedCaptureGroup(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::SaveLeftNamedCaptureGroup; }
ALWAYS_INLINE size_t size() const override { return 3; }
@@ -715,10 +660,6 @@ public:
class OpCode_SaveRightNamedCaptureGroup final : public OpCode {
public:
- OpCode_SaveRightNamedCaptureGroup(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::SaveRightNamedCaptureGroup; }
ALWAYS_INLINE size_t size() const override { return 3; }
@@ -732,10 +673,6 @@ public:
class OpCode_Compare final : public OpCode {
public:
- OpCode_Compare(ByteCode& bytecode)
- : OpCode(bytecode)
- {
- }
ExecutionResult execute(const MatchInput& input, MatchState& state, MatchOutput& output) const override;
ALWAYS_INLINE OpCodeId opcode_id() const override { return OpCodeId::Compare; }
ALWAYS_INLINE size_t size() const override { return arguments_size() + 3; }