Jacek Caban : jscript: Added parser memory managment.

Alexandre Julliard julliard at winehq.org
Thu Sep 4 08:26:58 CDT 2008


Module: wine
Branch: master
Commit: 720e8c625225a91109c77ce11c34e4e2dc3977be
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=720e8c625225a91109c77ce11c34e4e2dc3977be

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep  3 00:26:10 2008 +0200

jscript: Added parser memory managment.

---

 dlls/jscript/Makefile.in |    1 +
 dlls/jscript/engine.h    |    7 ++-
 dlls/jscript/jscript.h   |   19 ++++++++
 dlls/jscript/jsutils.c   |  112 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/jscript/parser.y    |    5 ++
 5 files changed, 142 insertions(+), 2 deletions(-)

diff --git a/dlls/jscript/Makefile.in b/dlls/jscript/Makefile.in
index 3ccfae3..96d8c37 100644
--- a/dlls/jscript/Makefile.in
+++ b/dlls/jscript/Makefile.in
@@ -12,6 +12,7 @@ C_SRCS = \
 	engine.c \
 	jscript.c \
 	jscript_main.c \
+	jsutils.c \
 	lex.c
 
 IDL_TLB_SRCS = jsglobal.idl
diff --git a/dlls/jscript/engine.h b/dlls/jscript/engine.h
index 3e558bd..1fad3dd 100644
--- a/dlls/jscript/engine.h
+++ b/dlls/jscript/engine.h
@@ -29,6 +29,9 @@ typedef struct _parser_ctx_t {
     source_elements_t *source;
     BOOL nl;
     HRESULT hres;
+
+    jsheap_t tmp_heap;
+    jsheap_t heap;
 } parser_ctx_t;
 
 HRESULT script_parse(script_ctx_t*,const WCHAR*,parser_ctx_t**);
@@ -43,12 +46,12 @@ static inline void parser_addref(parser_ctx_t *ctx)
 
 static inline void *parser_alloc(parser_ctx_t *ctx, DWORD size)
 {
-    return heap_alloc(size); /* FIXME */
+    return jsheap_alloc(&ctx->heap, size);
 }
 
 static inline void *parser_alloc_tmp(parser_ctx_t *ctx, DWORD size)
 {
-    return heap_alloc(size); /* FIXME */
+    return jsheap_alloc(&ctx->tmp_heap, size);
 }
 
 typedef struct {
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 6f43adc..ffb3f2b 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -29,6 +29,7 @@
 #include "activscp.h"
 
 #include "wine/unicode.h"
+#include "wine/list.h"
 
 typedef struct _script_ctx_t script_ctx_t;
 
@@ -62,6 +63,19 @@ static void inline script_addref(script_ctx_t *ctx)
 
 HRESULT WINAPI JScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);
 
+typedef struct {
+    void **blocks;
+    DWORD block_cnt;
+    DWORD last_block;
+    DWORD offset;
+    struct list custom_blocks;
+} jsheap_t;
+
+void jsheap_init(jsheap_t*);
+void *jsheap_alloc(jsheap_t*,DWORD);
+void jsheap_clear(jsheap_t*);
+void jsheap_free(jsheap_t*);
+
 extern LONG module_ref;
 
 static inline void lock_module(void)
@@ -84,6 +98,11 @@ static inline void *heap_alloc_zero(size_t len)
     return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
 }
 
+static inline void *heap_realloc(void *mem, size_t len)
+{
+    return HeapReAlloc(GetProcessHeap(), 0, mem, len);
+}
+
 static inline BOOL heap_free(void *mem)
 {
     return HeapFree(GetProcessHeap(), 0, mem);
diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c
new file mode 100644
index 0000000..4f84e88
--- /dev/null
+++ b/dlls/jscript/jsutils.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2008 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "jscript.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(jscript);
+
+#define MIN_BLOCK_SIZE  128
+
+static inline DWORD block_size(DWORD block)
+{
+    return MIN_BLOCK_SIZE << block;
+}
+
+void jsheap_init(jsheap_t *heap)
+{
+    memset(heap, 0, sizeof(*heap));
+    list_init(&heap->custom_blocks);
+}
+
+void *jsheap_alloc(jsheap_t *heap, DWORD size)
+{
+    struct list *list;
+    void *tmp;
+
+    if(!heap->block_cnt) {
+        if(!heap->blocks) {
+            heap->blocks = heap_alloc(sizeof(void*));
+            if(!heap->blocks)
+                return NULL;
+        }
+
+        tmp = heap_alloc(block_size(0));
+        if(!tmp)
+            return NULL;
+
+        heap->blocks[0] = tmp;
+        heap->block_cnt = 1;
+    }
+
+    if(heap->offset + size < block_size(heap->last_block)) {
+        tmp = ((BYTE*)heap->blocks[heap->last_block])+heap->offset;
+        heap->offset += size;
+        return tmp;
+    }
+
+    if(size < block_size(heap->last_block+1)) {
+        if(heap->last_block+1 == heap->block_cnt) {
+            tmp = heap_realloc(heap->blocks, (heap->block_cnt+1)*sizeof(void*));
+            if(!tmp)
+                return NULL;
+            heap->blocks = tmp;
+        }
+
+        tmp = heap_alloc(block_size(heap->block_cnt+1));
+        if(!tmp)
+            return NULL;
+
+        heap->blocks[heap->block_cnt++] = tmp;
+
+        heap->last_block++;
+        heap->offset = size;
+        return heap->blocks[heap->last_block];
+    }
+
+    list = heap_alloc(size + sizeof(struct list));
+    if(!list)
+        return NULL;
+
+    list_add_head(&heap->custom_blocks, list);
+    return list+1;
+}
+
+void jsheap_clear(jsheap_t *heap)
+{
+    struct list *tmp;
+
+    while((tmp = list_next(&heap->custom_blocks, &heap->custom_blocks))) {
+        list_remove(tmp);
+        heap_free(tmp);
+    }
+}
+
+void jsheap_free(jsheap_t *heap)
+{
+    DWORD i;
+
+    jsheap_clear(heap);
+
+    for(i=0; i < heap->block_cnt; i++)
+        heap_free(heap->blocks[i]);
+    heap_free(heap->blocks);
+
+    jsheap_init(heap);
+}
diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y
index dc96647..15584ca 100644
--- a/dlls/jscript/parser.y
+++ b/dlls/jscript/parser.y
@@ -1512,6 +1512,7 @@ void parser_release(parser_ctx_t *ctx)
     if(--ctx->ref)
         return;
 
+    jsheap_free(&ctx->heap);
     heap_free(ctx);
 }
 
@@ -1533,7 +1534,11 @@ HRESULT script_parse(script_ctx_t *ctx, const WCHAR *code, parser_ctx_t **ret)
     script_addref(ctx);
     parser_ctx->script = ctx;
 
+    jsheap_init(&parser_ctx->tmp_heap);
+    jsheap_init(&parser_ctx->heap);
+
     parser_parse(parser_ctx);
+    jsheap_free(&parser_ctx->tmp_heap);
     if(FAILED(parser_ctx->hres)) {
         hres = parser_ctx->hres;
         parser_release(parser_ctx);




More information about the wine-cvs mailing list