diff options
| author | Thiago de Arruda <tpadilha84@gmail.com> | 2015-04-13 09:30:57 -0300 |
|---|---|---|
| committer | Thiago de Arruda <tpadilha84@gmail.com> | 2015-04-13 09:30:57 -0300 |
| commit | a9ee85b9fc2d4e3faa466e9c3062cd41315f8456 (patch) | |
| tree | e45187575c9f0397c5d717780b61adf5b3976a62 | |
| parent | 0248c75bc190ec2fbc8f3af3d61f771e76d628d6 (diff) | |
| parent | 2d104f14dbd2c60a30e9e1e0fef098b39db087db (diff) | |
| download | rneovim-a9ee85b9fc2d4e3faa466e9c3062cd41315f8456.tar.gz rneovim-a9ee85b9fc2d4e3faa466e9c3062cd41315f8456.tar.bz2 rneovim-a9ee85b9fc2d4e3faa466e9c3062cd41315f8456.zip | |
Merge PR #2415 'Use jemalloc instead of libc allocator'
79 files changed, 1519 insertions, 1420 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4219c69b62..3ab7062019 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,6 +202,29 @@ option(LIBVTERM_USE_STATIC "Use static libvterm" ON) find_package(LibVterm REQUIRED) include_directories(SYSTEM ${LIBVTERM_INCLUDE_DIRS}) +option(SANITIZE "Enable Clang sanitizers for nvim binary" OFF) +if(SANITIZE AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang") + message(WARNING "SANITIZE is only supported for Clang ... disabling") + set(SANITIZE OFF) +endif() + +if(SANITIZE) + option(USE_JEMALLOC "Use jemalloc" OFF) +else() + option(USE_JEMALLOC "Use jemalloc" ON) +endif() + +if(USE_JEMALLOC) + option(JEMALLOC_USE_STATIC "Use static jemalloc" ON) + find_package(JeMalloc) + if(JEMALLOC_FOUND) + message(STATUS "Using jemalloc instead of libc allocator") + include_directories(SYSTEM ${JEMALLOC_INCLUDE_DIRS}) + else() + set(USE_JEMALLOC OFF) + endif() +endif() + find_package(LibIntl) if(LibIntl_FOUND) include_directories(SYSTEM ${LibIntl_INCLUDE_DIRS}) @@ -1274,6 +1274,39 @@ def CheckPosixThreading(filename, clean_lines, linenum, error): ' see os_localtime_r for an example.') +memory_functions = ( + ('malloc(', 'xmalloc('), + ('calloc(', 'xcalloc('), + ('realloc(', 'xrealloc('), + ('strdup(', 'xstrdup('), + ('free(', 'xfree('), +) +memory_ignore_pattern = re.compile(r'src/nvim/memory.c$') + + +def CheckMemoryFunctions(filename, clean_lines, linenum, error): + """Checks for calls to invalid functions. + + Args: + filename: The name of the current file. + clean_lines: A CleansedLines instance containing the file. + linenum: The number of the line to check. + error: The function to call with any errors found. + """ + if memory_ignore_pattern.search(filename): + return + line = clean_lines.elided[linenum] + for function, suggested_function in memory_functions: + ix = line.find(function) + # Comparisons made explicit for clarity -- pylint: + # disable=g-explicit-bool-comparison + if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and + line[ix - 1] not in ('_', '.', '>'))): + error(filename, linenum, 'runtime/memory_fn', 2, + 'Use ' + suggested_function + + '...) instead of ' + function + '...).') + + # Matches invalid increment: *count++, which moves pointer instead of # incrementing a value. _RE_PATTERN_INVALID_INCREMENT = re.compile( @@ -2925,6 +2958,7 @@ def ProcessLine(filename, file_extension, clean_lines, line, CheckForNonStandardConstructs(filename, clean_lines, line, nesting_state, error) CheckPosixThreading(filename, clean_lines, line, error) + CheckMemoryFunctions(filename, clean_lines, line, error) for check_fn in extra_check_functions: check_fn(filename, clean_lines, line, error) diff --git a/cmake/FindJeMalloc.cmake b/cmake/FindJeMalloc.cmake new file mode 100644 index 0000000000..fd20a456fb --- /dev/null +++ b/cmake/FindJeMalloc.cmake @@ -0,0 +1,48 @@ +# - Try to find jemalloc +# Once done this will define +# JEMALLOC_FOUND - System has jemalloc +# JEMALLOC_INCLUDE_DIRS - The jemalloc include directories +# JEMALLOC_LIBRARIES - The libraries needed to use jemalloc + +find_package(PkgConfig) +if(NOT JEMALLOC_USE_BUNDLED) + find_package(PkgConfig) + if (PKG_CONFIG_FOUND) + pkg_check_modules(PC_JEMALLOC QUIET jemalloc) + endif() +else() + set(PC_JEMALLOC_INCLUDEDIR) + set(PC_JEMALLOC_INCLUDE_DIRS) + set(PC_JEMALLOC_LIBDIR) + set(PC_JEMALLOC_LIBRARY_DIRS) + set(LIMIT_SEARCH NO_DEFAULT_PATH) +endif() + +set(JEMALLOC_DEFINITIONS ${PC_JEMALLOC_CFLAGS_OTHER}) + +find_path(JEMALLOC_INCLUDE_DIR jemalloc/jemalloc.h + PATHS ${PC_JEMALLOC_INCLUDEDIR} ${PC_JEMALLOC_INCLUDE_DIRS} + ${LIMIT_SEARCH}) + +# If we're asked to use static linkage, add libjemalloc.a as a preferred library name. +if(JEMALLOC_USE_STATIC) + list(APPEND JEMALLOC_NAMES + "${CMAKE_STATIC_LIBRARY_PREFIX}jemalloc${CMAKE_STATIC_LIBRARY_SUFFIX}") +endif() + +list(APPEND JEMALLOC_NAMES jemalloc) + +find_library(JEMALLOC_LIBRARY NAMES ${JEMALLOC_NAMES} + HINTS ${PC_JEMALLOC_LIBDIR} ${PC_JEMALLOC_LIBRARY_DIRS} + ${LIMIT_SEARCH}) + +set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY}) +set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(JeMalloc DEFAULT_MSG + JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR) + +mark_as_advanced(JEMALLOC_INCLUDE_DIR JEMALLOC_LIBRARY) diff --git a/config/config.h.in b/config/config.h.in index 382b5c653d..04db12fbe3 100644 --- a/config/config.h.in +++ b/config/config.h.in @@ -65,5 +65,6 @@ #define FEAT_BROWSE #define FEAT_CSCOPE #define FEAT_MOUSE +#cmakedefine USE_JEMALLOC #endif // AUTO_CONFIG_H diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 09b709b6ce..dc44c9135d 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -1,11 +1,5 @@ include(CheckLibraryExists) -option(SANITIZE "Enable Clang sanitizers for nvim binary" OFF) -if(SANITIZE AND NOT CMAKE_C_COMPILER_ID MATCHES "Clang") - message(WARNING "SANITIZE is only supported for Clang ... disabling") - set(SANITIZE OFF) -endif() - set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto) set(DISPATCH_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/msgpack-gen.lua) file(GLOB API_HEADERS api/*.h) @@ -176,9 +170,16 @@ list(APPEND NVIM_LINK_LIBRARIES ${CMAKE_THREAD_LIBS_INIT} ) +set(NVIM_EXEC_LINK_LIBRARIES ${NVIM_LINK_LIBRARIES}) + +if(USE_JEMALLOC) + # dont use jemalloc in the unit test library + list(APPEND NVIM_EXEC_LINK_LIBRARIES ${JEMALLOC_LIBRARIES}) +endif() + add_executable(nvim ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} ${NEOVIM_HEADERS}) -target_link_libraries(nvim ${NVIM_LINK_LIBRARIES}) +target_link_libraries(nvim ${NVIM_EXEC_LINK_LIBRARIES}) install_helper(TARGETS nvim) if(SANITIZE) @@ -199,5 +200,6 @@ set_property(TARGET libnvim APPEND_STRING PROPERTY COMPILE_FLAGS " -DMAKE_LIB ") add_library(nvim-test MODULE EXCLUDE_FROM_ALL ${NEOVIM_GENERATED_SOURCES} ${NEOVIM_SOURCES} ${NEOVIM_HEADERS}) target_link_libraries(nvim-test ${NVIM_LINK_LIBRARIES}) +set_target_properties(nvim-test PROPERTIES COMPILE_FLAGS -DUNIT_TESTING) add_subdirectory(po) diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 5bd48fc19f..c9ada8dfc0 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -58,7 +58,7 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err) rv = slice.items[0].data.string; } - free(slice.items); + xfree(slice.items); return rv; } @@ -144,10 +144,10 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer, end: if (err->set) { for (size_t i = 0; i < rv.size; i++) { - free(rv.items[i].data.string.data); + xfree(rv.items[i].data.string.data); } - free(rv.items); + xfree(rv.items); rv.items = NULL; } @@ -280,7 +280,7 @@ void buffer_set_line_slice(Buffer buffer, } // Same as with replacing, but we also need to free lines - free(lines[i]); + xfree(lines[i]); lines[i] = NULL; extra++; } @@ -301,10 +301,10 @@ void buffer_set_line_slice(Buffer buffer, end: for (size_t i = 0; i < new_len; i++) { - free(lines[i]); + xfree(lines[i]); } - free(lines); + xfree(lines); restore_win_for_buf(save_curwin, save_curtab, save_curbuf); try_end(err); } diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 39ca0756f3..492da25a82 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -61,7 +61,7 @@ bool try_end(Error *err) free_global_msglist(); if (should_free) { - free(msg); + xfree(msg); } } else if (did_throw) { api_set_error(err, Exception, "%s", current_exception->value); @@ -489,7 +489,7 @@ void api_free_string(String value) return; } - free(value.data); + xfree(value.data); } void api_free_object(Object value) @@ -527,7 +527,7 @@ void api_free_array(Array value) api_free_object(value.items[i]); } - free(value.items); + xfree(value.items); } void api_free_dictionary(Dictionary value) @@ -537,7 +537,7 @@ void api_free_dictionary(Dictionary value) api_free_object(value.items[i].value); } - free(value.items); + xfree(value.items); } Dictionary api_metadata(void) diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 587e19fe35..1204c9e1d1 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -85,7 +85,7 @@ void vim_feedkeys(String keys, String mode, Boolean escape_csi) insert ? 0 : typebuf.tb_len, !typed, false); if (escape_csi) { - free(keys_esc); + xfree(keys_esc); } if (vgetc_busy) diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 11cb7bdeac..4585278714 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -443,8 +443,8 @@ close_buffer ( * Remove the buffer from the list. */ if (wipe_buf) { - free(buf->b_ffname); - free(buf->b_sfname); + xfree(buf->b_ffname); + xfree(buf->b_sfname); if (buf->b_prev == NULL) firstbuf = buf->b_next; else @@ -563,7 +563,7 @@ static void free_buffer(buf_T *buf) buf->b_next = au_pending_free_buf; au_pending_free_buf = buf; } else { - free(buf); + xfree(buf); } } @@ -587,7 +587,7 @@ free_buffer_stuff ( buf_delete_signs(buf); /* delete any signs */ map_clear_int(buf, MAP_ALL_MODES, TRUE, FALSE); /* clear local mappings */ map_clear_int(buf, MAP_ALL_MODES, TRUE, TRUE); /* clear local abbrevs */ - free(buf->b_start_fenc); + xfree(buf->b_start_fenc); buf->b_start_fenc = NULL; } @@ -605,7 +605,7 @@ static void clear_wininfo(buf_T *buf) clear_winopt(&wip->wi_opt); deleteFoldRecurse(&wip->wi_folds); } - free(wip); + xfree(wip); } } @@ -1332,7 +1332,7 @@ buflist_new ( if (ffname != NULL && !(flags & BLN_DUMMY) && (buf = buflist_findname_file_id(ffname, &file_id, file_id_valid)) != NULL) { - free(ffname); + xfree(ffname); if (lnum != 0) buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE); /* copy the options now, if 'cpo' doesn't have 's' and not done @@ -1396,9 +1396,9 @@ buflist_new ( buf->b_wininfo = xcalloc(1, sizeof(wininfo_T)); if (ffname != NULL && (buf->b_ffname == NULL || buf->b_sfname == NULL)) { - free(buf->b_ffname); + xfree(buf->b_ffname); buf->b_ffname = NULL; - free(buf->b_sfname); + xfree(buf->b_sfname); buf->b_sfname = NULL; if (buf != curbuf) free_buffer(buf); @@ -1672,7 +1672,7 @@ buf_T *buflist_findname_exp(char_u *fname) ); if (ffname != NULL) { buf = buflist_findname(ffname); - free(ffname); + xfree(ffname); } return buf; } @@ -1767,7 +1767,7 @@ buflist_findpat ( ++p; prog = vim_regcomp(p, p_magic ? RE_MAGIC : 0); if (prog == NULL) { - free(pat); + xfree(pat); return -1; } @@ -1809,7 +1809,7 @@ buflist_findpat ( find_listed = FALSE; } - free(pat); + xfree(pat); } if (match == -2) @@ -1855,7 +1855,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) prog = vim_regcomp(patc + attempt * 11, RE_MAGIC); if (prog == NULL) { if (patc != pat) - free(patc); + xfree(patc); return FAIL; } @@ -1893,7 +1893,7 @@ int ExpandBufnames(char_u *pat, int *num_file, char_u ***file, int options) } if (patc != pat) - free(patc); + xfree(patc); *num_file = count; return count == 0 ? FAIL : OK; @@ -1938,7 +1938,7 @@ static char_u *fname_match(regprog_T *prog, char_u *name, bool ignore_case) p = home_replace_save(NULL, name); if (vim_regexec(®match, p, (colnr_T)0)) match = name; - free(p); + xfree(p); } } @@ -2223,8 +2223,8 @@ setfname ( if (ffname == NULL || *ffname == NUL) { /* Removing the name. */ - free(buf->b_ffname); - free(buf->b_sfname); + xfree(buf->b_ffname); + xfree(buf->b_sfname); buf->b_ffname = NULL; buf->b_sfname = NULL; } else { @@ -2245,7 +2245,7 @@ setfname ( if (obuf->b_ml.ml_mfp != NULL) { /* it's loaded, fail */ if (message) EMSG(_("E95: Buffer with this name already exists")); - free(ffname); + xfree(ffname); return FAIL; } /* delete from the list */ @@ -2255,8 +2255,8 @@ setfname ( #ifdef USE_FNAME_CASE path_fix_case(sfname); /* set correct case for short file name */ #endif - free(buf->b_ffname); - free(buf->b_sfname); + xfree(buf->b_ffname); + xfree(buf->b_sfname); buf->b_ffname = ffname; buf->b_sfname = sfname; } @@ -2282,8 +2282,8 @@ void buf_set_name(int fnum, char_u *name) buf = buflist_findnr(fnum); if (buf != NULL) { - free(buf->b_sfname); - free(buf->b_ffname); + xfree(buf->b_sfname); + xfree(buf->b_ffname); buf->b_ffname = vim_strsave(name); buf->b_sfname = NULL; /* Allocate ffname and expand into full path. Also resolves .lnk @@ -2561,7 +2561,7 @@ fileinfo ( set_keep_msg(p, 0); } - free(buffer); + xfree(buffer); } void col_print(char_u *buf, size_t buflen, int col, int vcol) @@ -2636,7 +2636,7 @@ void maketitle(void) else { p = transstr(path_tail(curbuf->b_fname)); STRLCPY(buf, p, SPACE_FOR_FNAME + 1); - free(p); + xfree(p); } switch (bufIsChanged(curbuf) @@ -2677,7 +2677,7 @@ void maketitle(void) if (off < SPACE_FOR_DIR) { p = transstr(buf + off); STRLCPY(buf + off, p, SPACE_FOR_DIR - off + 1); - free(p); + xfree(p); } else { STRLCPY(buf + off, "...", SPACE_FOR_ARGNR - off + 1); } @@ -2749,7 +2749,7 @@ static int ti_change(char_u *str, char_u **last) { if ((str == NULL) != (*last == NULL) || (str != NULL && *last != NULL && STRCMP(str, *last) != 0)) { - free(*last); + xfree(*last); if (str == NULL) *last |