Bläddra i källkod

LibRegex: Avoid initialization checks in get_opcode_by_id()

Gunnar Beutner 4 år sedan
förälder
incheckning
d3c2a3caea
2 ändrade filer med 65 tillägg och 125 borttagningar
  1. 57 54
      Userland/Libraries/LibRegex/RegexByteCode.cpp
  2. 8 71
      Userland/Libraries/LibRegex/RegexByteCode.h

+ 57 - 54
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];

+ 8 - 71
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; }