]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - parser/ParserArena.h
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / parser / ParserArena.h
index 1563e498f416cef00c3cb9fff3b6a52426ba3794..45d4b158ee1c5b58b36d6e75cc3bf1c162a5a1f0 100644 (file)
@@ -42,40 +42,78 @@ namespace JSC {
             clear();
         }
 
-        ALWAYS_INLINE const Identifier& makeIdentifier(JSGlobalData*, const UChar* characters, size_t length);
-        const Identifier& makeNumericIdentifier(JSGlobalData*, double number);
+        template <typename T>
+        ALWAYS_INLINE const Identifier& makeIdentifier(VM*, const T* characters, size_t length);
+        ALWAYS_INLINE const Identifier& makeIdentifierLCharFromUChar(VM*, const UChar* characters, size_t length);
 
+        const Identifier& makeNumericIdentifier(VM*, double number);
+
+        bool isEmpty() const { return m_identifiers.isEmpty(); }
+
+    public:
+        static const int MaximumCachableCharacter = 128;
+        typedef SegmentedVector<Identifier, 64> IdentifierVector;
         void clear()
         {
             m_identifiers.clear();
-            for (unsigned  i = 0; i < 128; i++)
+            for (int i = 0; i < MaximumCachableCharacter; i++)
                 m_shortIdentifiers[i] = 0;
+            for (int i = 0; i < MaximumCachableCharacter; i++)
+                m_recentIdentifiers[i] = 0;
         }
-        bool isEmpty() const { return m_identifiers.isEmpty(); }
 
     private:
-        static const int MaximumCachableCharacter = 128;
-        typedef SegmentedVector<Identifier, 64> IdentifierVector;
         IdentifierVector m_identifiers;
         FixedArray<Identifier*, MaximumCachableCharacter> m_shortIdentifiers;
+        FixedArray<Identifier*, MaximumCachableCharacter> m_recentIdentifiers;
     };
 
-    ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifier(JSGlobalData* globalData, const UChar* characters, size_t length)
+    template <typename T>
+    ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifier(VM* vm, const T* characters, size_t length)
     {
-        if (length == 1 && characters[0] < MaximumCachableCharacter) {
+        if (characters[0] >= MaximumCachableCharacter) {
+            m_identifiers.append(Identifier(vm, characters, length));
+            return m_identifiers.last();
+        }
+        if (length == 1) {
             if (Identifier* ident = m_shortIdentifiers[characters[0]])
                 return *ident;
-            m_identifiers.append(Identifier(globalData, characters, length));
+            m_identifiers.append(Identifier(vm, characters, length));
             m_shortIdentifiers[characters[0]] = &m_identifiers.last();
             return m_identifiers.last();
         }
-        m_identifiers.append(Identifier(globalData, characters, length));
+        Identifier* ident = m_recentIdentifiers[characters[0]];
+        if (ident && Identifier::equal(ident->impl(), characters, length))
+            return *ident;
+        m_identifiers.append(Identifier(vm, characters, length));
+        m_recentIdentifiers[characters[0]] = &m_identifiers.last();
         return m_identifiers.last();
     }
 
-    inline const Identifier& IdentifierArena::makeNumericIdentifier(JSGlobalData* globalData, double number)
+    ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifierLCharFromUChar(VM* vm, const UChar* characters, size_t length)
     {
-        m_identifiers.append(Identifier(globalData, UString::number(number)));
+        if (characters[0] >= MaximumCachableCharacter) {
+            m_identifiers.append(Identifier::createLCharFromUChar(vm, characters, length));
+            return m_identifiers.last();
+        }
+        if (length == 1) {
+            if (Identifier* ident = m_shortIdentifiers[characters[0]])
+                return *ident;
+            m_identifiers.append(Identifier(vm, characters, length));
+            m_shortIdentifiers[characters[0]] = &m_identifiers.last();
+            return m_identifiers.last();
+        }
+        Identifier* ident = m_recentIdentifiers[characters[0]];
+        if (ident && Identifier::equal(ident->impl(), characters, length))
+            return *ident;
+        m_identifiers.append(Identifier::createLCharFromUChar(vm, characters, length));
+        m_recentIdentifiers[characters[0]] = &m_identifiers.last();
+        return m_identifiers.last();
+    }
+    
+    inline const Identifier& IdentifierArena::makeNumericIdentifier(VM* vm, double number)
+    {
+        m_identifiers.append(Identifier(vm, String::numberToStringECMAScript(number)));
         return m_identifiers.last();
     }
 
@@ -110,7 +148,7 @@ namespace JSC {
 
         void* allocateDeletable(size_t size)
         {
-            ParserArenaDeletable* deletable = static_cast<ParserArenaDeletable*>(fastMalloc(size));
+            ParserArenaDeletable* deletable = static_cast<ParserArenaDeletable*>(allocateFreeable(size));
             m_deletableObjects.append(deletable);
             return deletable;
         }
@@ -121,9 +159,14 @@ namespace JSC {
         void removeLast();
 
         bool isEmpty() const;
-        void reset();
+        JS_EXPORT_PRIVATE void reset();
 
-        IdentifierArena& identifierArena() { return *m_identifierArena; }
+        IdentifierArena& identifierArena()
+        {
+            if (UNLIKELY (!m_identifierArena))
+                m_identifierArena = adoptPtr(new IdentifierArena);
+            return *m_identifierArena;
+        }
 
     private:
         static const size_t freeablePoolSize = 8000;