Module: wine Branch: master Commit: 720e8c625225a91109c77ce11c34e4e2dc3977be URL: http://source.winehq.org/git/wine.git/?a=commit;h=720e8c625225a91109c77ce11c...
Author: Jacek Caban jacek@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);