diff --git a/working_vm/make/vm/port.xml b/working_vm/make/vm/port.xml
index 0a8ca3a..64a8974 100755
--- a/working_vm/make/vm/port.xml
+++ b/working_vm/make/vm/port.xml
@@ -62,6 +62,7 @@
+
diff --git a/working_vm/make/vm/port_ch.xml b/working_vm/make/vm/port_ch.xml
index b41eaff..2661df8 100755
--- a/working_vm/make/vm/port_ch.xml
+++ b/working_vm/make/vm/port_ch.xml
@@ -95,6 +95,7 @@
+
diff --git a/working_vm/vm/port/include/port_malloc.h b/working_vm/vm/port/include/port_malloc.h
index 489b84f..1ddea9b 100755
--- a/working_vm/vm/port/include/port_malloc.h
+++ b/working_vm/vm/port/include/port_malloc.h
@@ -14,26 +14,148 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
- * @author Evgueni Brevnov
+/**
+ * @author Evgueni Brevnov, Andrey Yakushev
* @version $Revision: 1.1.2.1.4.4 $
- */
+ */
#ifndef _PORT_MALLOC_H_
#define _PORT_MALLOC_H_
+#include "port_general.h"
#ifdef WIN32
-#include
+ #include
+#else
+ #include
+#endif
+
+#ifdef __cplusplus
+ #define INLINE inline
#else
-#include
+ #ifdef WIN32
+ #define INLINE __forceinline
+ #else
+ #define INLINE static
+ #endif
#endif
-// FIXME
-// Very basic memory allocation utilities
+/**
+ * If defined then debug variants of memory allocation functions (malloc,
+ * free etc.) are used.
+ * They provides additional functionaliy, like detailed statistic and
+ * memory leackage control.
+ */
+//#define _MEMMGR
+
+/** Pool name for java.lang.management usage */
+#define NATIVE_POOL_NAME "Native Memory Pool"
+
+/** Defailt file name for feporting the memory usage informaion */
+#define MALLOC_LOG_FILE_NAME "malloc.log"
+
+#ifdef _MEMMGR
+ /** If defined then all native allocations and deallocations will be loged in MALLOC_LOG_FILE_NAME */
+ #define _MEMMGR_LOG
+ /** If defined then report of currently unfreed memory will be loged in MALLOC_LOG_FILE_NAME */
+ #define _MEMMGR_REPORT
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ /**
+ * Wrapper for standard free function. Used if _MEMMGR is defined.
+ * Provides checking for suquential call with the same address, and memory leackage.
+ * @param[in] APTR - address of memory block which would be checked ant passed
+ * to free function
+ * @param[in] file_name - file name where port_free is called
+ * @param[in] file_line - file line number where port_free is called
+ */
+ APR_DECLARE(void) port_free(void *APTR, char *file_name, int file_line);
+
+ /**
+ * Wrapper for standard malloc function. Used if _MEMMGR is defined.
+ * Provides storing arguments info about this call for statistics and additinal control, like
+ * memory leackage.
+ * @param[in] NBYTES - size in bytes passed to malloc function
+ * @param[in] file_name - file name where port_malloc is called
+ * @param[in] file_line - file line number where port_malloc is called
+ */
+ APR_DECLARE(void*) port_malloc(size_t NBYTES, char *file_name, int file_line);
+
+ /**
+ * Initiates memory control system. Used if _MEMMGR is defined. All memory allocation
+ * and releasing calls would be monitored futher. Explicit initialization is requirred
+ * for controling memory management during defined execution range.
+ */
+ void start_monitor_malloc();
+
+ /**
+ * Stops memory control system. Used if _MEMMGR is defined. Provides generation of detailed
+ * statistics at this place.
+ */
+ void report_leaked_malloc();
+
+ /**
+ * Returns size of memory in bytes currently used by port_malloc.
+ * @return size of memory in bytes currently used by port_malloc.
+ */
+ size_t port_mem_used_size();
+
+ /**
+ * Returns size of memory in bytes currently reserved by port_malloc.
+ * @return size of memory in bytes currently reserved by port_malloc.
+ */
+ size_t port_mem_reserved_size();
+
+ /**
+ * Returns size of committed memory in bytes currently used by port_malloc.
+ * @return size of committed memory in bytes currently used by port_malloc.
+ */
+ size_t port_mem_committed_size();
+
+ /**
+ * Returns maximum size of memory in bytes which could be used by port_malloc.
+ * @return maximum size of memory in bytes which could be used by port_malloc.
+ */
+ size_t port_mem_max_size();
+
+ #ifdef _MEMMGR_LOG
+
+ #define _MEMMGR_LOG_OR_REPORT
+ #define MEMMGR_LOG(m) fprintf m;
+ #else
+ #define MEMMGR_LOG(m)
+ #endif
+
+ #ifdef _MEMMGR_REPORT
+ #define _MEMMGR_LOG_OR_REPORT
+ #endif
+
+ #ifdef __cplusplus
+ }
+ #endif
+
-#define STD_FREE(p) free(p)
-#define STD_MALLOC(s) malloc(s)
-#define STD_CALLOC(n, s) calloc(n, s)
-#define STD_REALLOC(p, s) realloc(p, s)
-#define STD_ALLOCA(s) alloca(s)
+ #ifdef STRESS_MALLOC
+ // TODO: implement here small preallocated malloc for out of memory conditions
+ #define STD_FREE(p) free(p)
+ #define STD_MALLOC(s) malloc(s)
+ #define STD_CALLOC(n, s) calloc(n, s)
+ #define STD_REALLOC(p, s) realloc(p, s)
+ #define STD_ALLOCA(s) alloca(s)
+ #else // not defined STRESS_MALLOC
+ #define STD_FREE(p) port_free(p, __FILE__, __LINE__)
+ #define STD_MALLOC(s) port_malloc(s, __FILE__, __LINE__)
+ #define STD_CALLOC(n, s) calloc(n, s)
+ #define STD_REALLOC(p, s) realloc(p, s)
+ #define STD_ALLOCA(s) alloca(s)
+ #endif //STRESS_MALLOC
+#else // not defined _MEMMGR
+ #define STD_FREE(p) free(p)
+ #define STD_MALLOC(s) malloc(s)
+ #define STD_CALLOC(n, s) calloc(n, s)
+ #define STD_REALLOC(p, s) realloc(p, s)
+ #define STD_ALLOCA(s) alloca(s)
+#endif // _MEMMGR
#endif // _PORT_MALLOC_H_
diff --git a/working_vm/vm/port/src/malloc/port_malloc.cpp b/working_vm/vm/port/src/malloc/port_malloc.cpp
new file mode 100755
index 0000000..49edfda
--- /dev/null
+++ b/working_vm/vm/port/src/malloc/port_malloc.cpp
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Andrey Yakushev
+ */
+
+
+#ifdef WIN32
+#include
+#include
+#include
+#else
+#include
+#endif
+
+#include "port_malloc.h"
+#include "port_malloc_registrar.h"
+
+#ifdef _MEMMGR
+
+extern "C" {
+
+#define MALLOC_LOG_FILE_NAME "malloc.log"
+
+static size_t mem_used_size = 0;
+static size_t mem_committed_size = 0;
+static size_t mem_reserved_size = 0;
+static size_t mem_max_size = UINT_MAX;
+
+static MallocRegistrar* malloc_registrar;
+
+void start_monitor_malloc() {
+ malloc_registrar = new MallocRegistrar();
+}
+
+void report_leaked_malloc() {
+ malloc_registrar->report();
+}
+
+size_t port_mem_used_size() {
+ return mem_used_size;
+}
+
+size_t port_mem_committed_size() {
+ return mem_committed_size;
+}
+
+size_t port_mem_reserved_size() {
+ return mem_reserved_size;
+}
+
+size_t port_mem_max_size() {
+ return mem_max_size;
+}
+
+
+APR_DECLARE(void*) port_malloc(size_t NBYTES, char *file_name, int file_line) {
+ void *result = malloc(NBYTES);
+ mem_used_size += NBYTES;
+ if (NULL != malloc_registrar) {
+ malloc_registrar->register_chunk(result, new ChunkAttributes(NBYTES, file_name, file_line));
+ MEMMGR_LOG((malloc_registrar->f_malloc_log,
+ "malloc(%08u)=%08x from %s:%u\n",
+ NBYTES,
+ result,
+ file_name,
+ file_line));
+ fflush(malloc_registrar->f_malloc_log);
+ }
+ return result;
+}
+
+APR_DECLARE(void) port_free(void *APTR, char *file_name, int file_line) {
+ if (NULL == malloc_registrar) return;
+ ChunkAttributes* attr = malloc_registrar->unregister_chunk(APTR);
+ if (NULL == attr) {
+ if (NULL == APTR) return;
+ MEMMGR_LOG((malloc_registrar->f_malloc_log,
+ "Probably double free call for %08x from %s:%u\n",
+ APTR,
+ file_name,
+ file_line));
+ fflush(malloc_registrar->f_malloc_log);
+ return;
+ }
+ free(APTR);
+ mem_used_size -= attr->size;
+ MEMMGR_LOG((malloc_registrar->f_malloc_log,
+ "free(%08x) at %s:%u\n malloc(%08u) from %s:%u\n current allocated size = %u\n",
+ APTR,
+ file_name,
+ file_line,
+ attr->size,
+ attr->file_name,
+ attr->file_line,
+ mem_used_size));
+ fflush(malloc_registrar->f_malloc_log);
+ free(attr);
+}
+
+} // extern "C"
+
+#endif // _MEMMGR
diff --git a/working_vm/vm/port/src/malloc/port_malloc_registrar.cpp b/working_vm/vm/port/src/malloc/port_malloc_registrar.cpp
new file mode 100755
index 0000000..094d566
--- /dev/null
+++ b/working_vm/vm/port/src/malloc/port_malloc_registrar.cpp
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Andrey Yakushev
+ * @version $Revision: 1.1.2.1.4.5 $
+ */
+
+#ifdef WIN32
+#include
+#include
+#else
+#include
+#endif
+
+#include "port_malloc_registrar.h"
+#include "log_macro.h"
+#include "port_malloc.h"
+
+#ifdef _MEMMGR
+
+ChunkAttributes::ChunkAttributes(size_t size, char *file_name, int file_line) {
+ this->size = size;
+ this->file_name = file_name;
+ this->file_line = file_line;
+}
+
+MallocRegistrar::MallocRegistrar() {
+#ifdef _MEMMGR_LOG_OR_REPORT
+ f_malloc_log = fopen(MALLOC_LOG_FILE_NAME, "w");
+ if( f_malloc_log == NULL) {
+ f_malloc_log = stdout;
+ };
+ MEMMGR_LOG((f_malloc_log, "MallocRegistrar::MallocRegistrar invoked\n"));
+#endif
+ mallocCellar = new MallocCellar();
+ mutex = CreateMutex(NULL, FALSE, NULL);
+}
+
+MallocRegistrar::~MallocRegistrar() {
+ MEMMGR_LOG((f_malloc_log, "MallocRegistrar::~MallocRegistrar invoked\n"));
+ fflush(f_malloc_log);
+ mutex = NULL;
+}
+
+void MallocRegistrar::report() {
+ if (mutex == NULL) return;
+ WaitForSingleObject(mutex, 0);
+ MEMMGR_LOG((f_malloc_log, "Malloc leakage report:\n"));
+ for (MallocCellarCI i = mallocCellar->begin(); i!=mallocCellar->end(); ++i) {
+ if (NULL == i->second) {
+ fprintf(f_malloc_log, "NULL record in mallocCellar\n");
+ return;
+ }
+ ChunkAttributes* attr = i->second;
+ fprintf(f_malloc_log, "unfreed pointer %08x size %08u from %s:%u\n", i->first, attr->size, attr->file_name, attr->file_line);
+ };
+ fflush(f_malloc_log);
+ ReleaseMutex(mutex);
+}
+
+void MallocRegistrar::register_chunk(void *APTR, ChunkAttributes* attr){
+ if (mutex == NULL) return;
+ WaitForSingleObject(mutex, 0);
+ MallocCellarCI i = mallocCellar->find(APTR);
+ if (i != mallocCellar->end()) { // found
+ MEMMGR_LOG((f_malloc_log, "Such chunk already exists\n"));
+ fflush(f_malloc_log);
+ return;
+ }
+ (*mallocCellar)[APTR] = attr;
+ ReleaseMutex(mutex);
+}
+
+ChunkAttributes* MallocRegistrar::unregister_chunk(void *APTR){
+ if (mutex == NULL) return NULL;
+ WaitForSingleObject(mutex, 0);
+ MallocCellarCI i = mallocCellar->find(APTR);
+ if (i == mallocCellar->end()) return NULL; // not found
+ ChunkAttributes* result = i->second;
+ mallocCellar->erase(APTR);
+ ReleaseMutex(mutex);
+ return result;
+}
+
+#endif // _MEMMGR
diff --git a/working_vm/vm/port/src/malloc/port_malloc_registrar.h b/working_vm/vm/port/src/malloc/port_malloc_registrar.h
new file mode 100755
index 0000000..0e4af7a
--- /dev/null
+++ b/working_vm/vm/port/src/malloc/port_malloc_registrar.h
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Andrey Yakushev
+ */
+#ifndef _PORT_MALLOC_REGISTRAR_H_
+#define _PORT_MALLOC_REGISTRAR_H_
+
+#ifdef WIN32
+#include
+#else
+#include
+#endif
+#include