@@ -107,7 +107,22 @@ struct _Node {
107107 NodeType type ;
108108};
109109
110+ #define NODE_SET_SIZE 50000
111+
112+ struct _NodeSet ;
113+ typedef struct _NodeSet NodeSet ;
114+ struct _NodeSet {
115+ /* link to next NodeSet */
116+ NodeSet * next ;
117+ /* Nodes in this Set */
118+ Node nodes [NODE_SET_SIZE ];
119+ size_t next_node ;
120+ };
121+
110122typedef struct {
123+ /* singly linked list of NodeSets */
124+ NodeSet * head_set ;
125+ NodeSet * tail_set ;
111126 /* linked list pointers */
112127 Node * head ;
113128 Node * tail ;
@@ -196,9 +211,24 @@ bool nodeEndsWith(Node* node, const char* string) {
196211 * ****************************************************************************
197212 */
198213/* allocates a new node */
199- Node * JsAllocNode () {
214+ Node * JsAllocNode (JsDoc * doc ) {
200215 Node * node ;
201- Newz (0 , node , 1 , Node );
216+ NodeSet * set = doc -> tail_set ;
217+
218+ /* if our current NodeSet is full, allocate a new NodeSet */
219+ if (set -> next_node >= NODE_SET_SIZE ) {
220+ NodeSet * next_set ;
221+ Newz (0 , next_set , 1 , NodeSet );
222+ set -> next = next_set ;
223+ doc -> tail_set = next_set ;
224+ set = next_set ;
225+ }
226+
227+ /* grab the next Node out of the NodeSet */
228+ node = set -> nodes + set -> next_node ;
229+ set -> next_node ++ ;
230+
231+ /* initialize the node */
202232 node -> prev = NULL ;
203233 node -> next = NULL ;
204234 node -> contents = NULL ;
@@ -207,20 +237,6 @@ Node* JsAllocNode() {
207237 return node ;
208238}
209239
210- /* frees the memory used by a node */
211- void JsFreeNode (Node * node ) {
212- if (node -> contents )
213- Safefree (node -> contents );
214- Safefree (node );
215- }
216- void JsFreeNodeList (Node * head ) {
217- while (head ) {
218- Node * tmp = head -> next ;
219- JsFreeNode (head );
220- head = tmp ;
221- }
222- }
223-
224240/* clears the contents of a node */
225241void JsClearNodeContents (Node * node ) {
226242 if (node -> contents )
@@ -246,7 +262,6 @@ void JsDiscardNode(Node* node) {
246262 node -> prev -> next = node -> next ;
247263 if (node -> next )
248264 node -> next -> prev = node -> prev ;
249- JsFreeNode (node );
250265}
251266
252267/* appends the node to the given element */
@@ -406,7 +421,7 @@ Node* JsTokenizeString(JsDoc* doc, const char* string) {
406421 /* parse the JS */
407422 while ((doc -> offset < doc -> length ) && (doc -> buffer [doc -> offset ])) {
408423 /* allocate a new node */
409- Node * node = JsAllocNode ();
424+ Node * node = JsAllocNode (doc );
410425 if (!doc -> head )
411426 doc -> head = node ;
412427 if (!doc -> tail )
@@ -686,6 +701,8 @@ char* JsMinify(const char* string) {
686701 doc .buffer = string ;
687702 doc .length = strlen (string );
688703 doc .offset = 0 ;
704+ Newz (0 , doc .head_set , 1 , NodeSet );
705+ doc .tail_set = doc .head_set ;
689706
690707 /* PASS 1: tokenize JS into a list of nodes */
691708 Node * head = JsTokenizeString (& doc , string );
@@ -713,8 +730,15 @@ char* JsMinify(const char* string) {
713730 }
714731 * ptr = 0 ;
715732 }
716- /* free memory used by node list */
717- JsFreeNodeList (head );
733+ /* free memory used by the NodeSets */
734+ {
735+ NodeSet * curr = doc .head_set ;
736+ while (curr ) {
737+ NodeSet * next = curr -> next ;
738+ Safefree (curr );
739+ curr = next ;
740+ }
741+ }
718742 /* return resulting minified JS back to caller */
719743 return results ;
720744}
0 commit comments