From a107644cf22efd09219fcef0b6ed7970249c306a Mon Sep 17 00:00:00 2001 From: jief Date: Mon, 6 Nov 2023 22:46:13 +0100 Subject: [PATCH] nanosvg memory allocation tracer. --- rEFIt_UEFI/libeg/VectorGraphics.cpp | 26 ++- rEFIt_UEFI/libeg/XTheme.cpp | 8 +- rEFIt_UEFI/libeg/XTheme.h | 5 +- rEFIt_UEFI/libeg/nanosvg.cpp | 260 ++++++++++++++++++++-------- rEFIt_UEFI/libeg/nanosvg.h | 24 ++- 5 files changed, 241 insertions(+), 82 deletions(-) diff --git a/rEFIt_UEFI/libeg/VectorGraphics.cpp b/rEFIt_UEFI/libeg/VectorGraphics.cpp index 03b4a4c0c..a88eb9676 100755 --- a/rEFIt_UEFI/libeg/VectorGraphics.cpp +++ b/rEFIt_UEFI/libeg/VectorGraphics.cpp @@ -211,15 +211,35 @@ EFI_STATUS XTheme::ParseSVGXIcon(INTN Id, const XString8& IconNameX, OUT XImage* return EFI_SUCCESS; } -EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer) +EFI_STATUS XTheme::ParseSVGXTheme(UINT8* buffer, UINTN Size) { EFI_STATUS Status; Icons.setEmpty(); +#if 1 && defined(NANOSVG_MEMORY_ALLOCATION_TRACE) +if ( nsvg__nbDanglingPtr() > 0 ) { + DBG("There is already dangling ptr. nano svg memory leak test not done\n"); +}else{ + char* buffer2 = (char*)malloc(Size); + memcpy(buffer2, buffer, Size); + nvsg__memoryallocation_verbose = false; + SVGParser = nsvgParse(buffer2, 72, 1.f); //the buffer will be modified, it is how nanosvg works // Jief : NEVER cast const to not const. Just change the parameter to not const !!! Nothing better to deceive. +// nsvg__deleteParser(SVGParser); + if ( nsvg__nbDanglingPtr() > 0 ) { + nsvg__outputDanglingPtr(); + nvsg__memoryallocation_verbose = true; // there leaks. Activate verbose + }else{ + nvsg__memoryallocation_verbose = false; // be sure that nvsg__memoryallocation_verbose is false, as it seems there is no memory leaks + } +} +#else + (void)Size; +#endif + // --- Parse theme.svg --- low case NSVGparser *mainParser = nsvgParse((CHAR8*)buffer, 72, 1.f); //the buffer will be modified, it is how nanosvg works - SVGParser = (void *)mainParser; //store the pointer for future use + SVGParser = mainParser; //store the pointer for future use NSVGimage *SVGimage = mainParser->image; if (!SVGimage) { // DBG("Theme not parsed!\n"); @@ -465,7 +485,7 @@ INTN renderSVGtext(XImage* TextBufferXY_ptr, INTN posX, INTN posY, INTN textType if (!p) { return 0; } - NSVGtext* text = (NSVGtext*)AllocateZeroPool(sizeof(NSVGtext)); + NSVGtext* text = (NSVGtext*)nsvg__alloczero(sizeof(NSVGtext), "renderSVGtext"_XS8); // use nsvg__alloczero method so it won't panic when it's freed. if (!text) { return 0; } diff --git a/rEFIt_UEFI/libeg/XTheme.cpp b/rEFIt_UEFI/libeg/XTheme.cpp index 51a0d0d45..07dc310c8 100644 --- a/rEFIt_UEFI/libeg/XTheme.cpp +++ b/rEFIt_UEFI/libeg/XTheme.cpp @@ -336,7 +336,7 @@ TagDict* XTheme::LoadTheme(const XStringW& TestTheme) { EFI_STATUS Status = EFI_UNSUPPORTED; TagDict* ThemeDict = NULL; - CHAR8 *ThemePtr = NULL; + UINT8 *ThemePtr = NULL; UINTN Size = 0; if (TestTheme.isEmpty()) { @@ -358,9 +358,9 @@ TagDict* XTheme::LoadTheme(const XStringW& TestTheme) } if (!EFI_ERROR(Status)) { - Status = egLoadFile(ThemeDir, CONFIG_THEME_SVG, (UINT8**)&ThemePtr, &Size); + Status = egLoadFile(ThemeDir, CONFIG_THEME_SVG, &ThemePtr, &Size); if (!EFI_ERROR(Status) && (ThemePtr != NULL) && (Size != 0)) { - Status = ParseSVGXTheme(ThemePtr); + Status = ParseSVGXTheme(ThemePtr, Size); if (EFI_ERROR(Status)) { ThemeDict = NULL; } else { @@ -374,7 +374,7 @@ TagDict* XTheme::LoadTheme(const XStringW& TestTheme) } else { Status = egLoadFile(ThemeDir, CONFIG_THEME_FILENAME, (UINT8**)&ThemePtr, &Size); if (!EFI_ERROR(Status) && (ThemePtr != NULL) && (Size != 0)) { - Status = ParseXML(ThemePtr, &ThemeDict, 0); + Status = ParseXML((CHAR8*)ThemePtr, &ThemeDict, 0); if (EFI_ERROR(Status)) { ThemeDict = NULL; } diff --git a/rEFIt_UEFI/libeg/XTheme.h b/rEFIt_UEFI/libeg/XTheme.h index 3a70e523b..923168697 100644 --- a/rEFIt_UEFI/libeg/XTheme.h +++ b/rEFIt_UEFI/libeg/XTheme.h @@ -1,6 +1,7 @@ #if !defined(__XTHEME_H__) #define __XTHEME_H__ +#include "nanosvg.h" #include "../cpp_foundation/XObjArray.h" #include "../cpp_foundation/XString.h" #include "../Settings/Self.h" @@ -145,7 +146,7 @@ public: XCinema Cinema; - void *SVGParser; + NSVGparser* SVGParser; void Init(); XTheme(); //default constructor @@ -184,7 +185,7 @@ public: void FillByDir(); EFI_STATUS GetThemeTagSettings(const TagDict* DictPointer); void parseTheme(void* p, char** dict); //in nano project - EFI_STATUS ParseSVGXTheme(const CHAR8* buffer); // in VectorTheme + EFI_STATUS ParseSVGXTheme(UINT8* buffer, UINTN Size); // in VectorTheme EFI_STATUS ParseSVGXIcon(INTN Id, const XString8& IconNameX, XImage* Image, void **SVGIcon); TagDict* LoadTheme(const XStringW& TestTheme); //return TagStruct* why? EFI_STATUS LoadSvgFrame(INTN i, OUT XImage* XFrame); // for animation diff --git a/rEFIt_UEFI/libeg/nanosvg.cpp b/rEFIt_UEFI/libeg/nanosvg.cpp index 34983e072..88b45054d 100755 --- a/rEFIt_UEFI/libeg/nanosvg.cpp +++ b/rEFIt_UEFI/libeg/nanosvg.cpp @@ -107,7 +107,122 @@ UINTN NumFrames; UINTN FrameTime; -int nsvg__shapesBound(NSVGshape *shapes, float* bounds); +//#define NANOSVG_MEMORY_ALLOCATION_TRACE + +#ifdef NANOSVG_MEMORY_ALLOCATION_TRACE +#include "../cpp_foundation/XString.h" + +int nvsg__memoryallocation_verbose = false; + +XArray allocatedPtr; +#ifdef NANOSVG_MEMORY_ALLOCATION_TRACE_VERBOSE +XObjArray allocatedPtrMsg; +#endif + +void* nsvg__alloc(UINTN size, const XString8& msg) +{ + void* buffer = AllocatePool(size); + if ( nvsg__memoryallocation_verbose ) DBG("nsvg__alloc(%lld) - %s = %llx\n", size, msg.c_str(), uintptr_t(buffer)); + allocatedPtr.Add(uintptr_t(buffer)); +#ifdef NANOSVG_MEMORY_ALLOCATION_TRACE_VERBOSE + allocatedPtrMsg.AddCopy(XString8(msg), true); +#endif + return buffer; +} + +void* nsvg__alloczero(UINTN size, const XString8& msg) +{ + void* buffer = AllocateZeroPool(size); + if ( nvsg__memoryallocation_verbose ) DBG("nsvg__alloczero(%lld) - %s = %llx\n", size, msg.c_str(), uintptr_t(buffer)); + allocatedPtr.Add(uintptr_t(buffer)); +#ifdef NANOSVG_MEMORY_ALLOCATION_TRACE_VERBOSE + allocatedPtrMsg.AddCopy(XString8(msg), true); +#endif + return buffer; +} + +void* nsvg__alloccopy(UINTN size, const void* ref, const XString8& msg) +{ + void* buffer = AllocateCopyPool(size, ref); + if ( nvsg__memoryallocation_verbose ) DBG("nsvg__alloccopy(%lld, %llx) - %s = %llx\n", size, uintptr_t(ref), msg.c_str(), uintptr_t(buffer)); + allocatedPtr.Add(uintptr_t(buffer)); +#ifdef NANOSVG_MEMORY_ALLOCATION_TRACE_VERBOSE + allocatedPtrMsg.AddCopy(XString8(msg), true); +#endif + return buffer; +} + +void* nsvg__realloc(UINTN oldsize, UINTN newsize, void* ref, const XString8& msg) +{ + uintptr_t ref2 = uintptr_t(ref); + auto idx = allocatedPtr.indexOf(ref2); + if ( idx == MAX_XSIZE ) log_technical_bug("nsvg__realloc"); + void* buffer = ReallocatePool(oldsize, newsize, ref); + if ( nvsg__memoryallocation_verbose ) DBG("nsvg__realloc(%lld, %lld, %llx) - %s = %llx\n", oldsize, newsize, uintptr_t(ref), msg.c_str(), uintptr_t(buffer)); + allocatedPtr.RemoveAtIndex(idx); +#ifdef NANOSVG_MEMORY_ALLOCATION_TRACE_VERBOSE + allocatedPtrMsg.RemoveAtIndex(idx); +#endif + allocatedPtr.Add(uintptr_t(buffer)); +#ifdef NANOSVG_MEMORY_ALLOCATION_TRACE_VERBOSE + allocatedPtrMsg.AddCopy(XString8(msg), true); +#endif + return buffer; +} + +void nsvg__delete(void* buffer, const XString8& msg) +{ +//if ( ThemeX->Icons.length() > 0 && buffer == ThemeX->Icons[0].ImageSVG ) { +// DBG("stop"); +//} + uintptr_t ref2 = uintptr_t(buffer); + auto idx = allocatedPtr.indexOf(ref2); + if ( idx == MAX_XSIZE ) { + log_technical_bug("nsvg__delete %llx", uintptr_t(buffer)); + } + EFI_STATUS Status = gBS->FreePool(buffer); + (void)Status; +#ifdef NANOSVG_MEMORY_ALLOCATION_TRACE_VERBOSE + if ( nvsg__memoryallocation_verbose ) DBG("nsvg__delete(%llx) - allocation msg %s - %s - Status = %s\n", uintptr_t(buffer), allocatedPtrMsg[idx].c_str(), msg.c_str(), efiStrError(Status)); +#else + if ( nvsg__memoryallocation_verbose ) DBG("nsvg__delete(%llx) - %s - Status = %s\n", uintptr_t(buffer), msg.c_str(), efiStrError(Status)); +#endif + allocatedPtr.RemoveAtIndex(idx); +#ifdef NANOSVG_MEMORY_ALLOCATION_TRACE_VERBOSE + allocatedPtrMsg.RemoveAtIndex(idx); +#endif +} + +size_t nsvg__nbDanglingPtr() +{ + return allocatedPtr.length(); +} + + +void nsvg__outputDanglingPtr() +{ + for(size_t i=0;iimage = (NSVGimage*)AllocateZeroPool(sizeof(NSVGimage)); + p->image = (NSVGimage*)nsvg__alloczero(sizeof(NSVGimage), "nsvg__createParser image"_XS8); if (p->image == NULL) { - FreePool(p); + nsvg__delete(p, "nsvg__createParser"_XS8); return NULL; } // Init style @@ -530,10 +646,10 @@ static void nsvg__deleteStyles(NSVGstyles* style) while (style) { NSVGstyles *next = style->next; if (style->name != NULL) - FreePool(style->name); + nsvg__delete(style->name, "nsvg__deleteStyles"_XS8); if (style->description != NULL) - FreePool(style->description); - FreePool(style); + nsvg__delete(style->description, "nsvg__deleteStyles"_XS8); + nsvg__delete(style, "nsvg__deleteStyles"_XS8); style = next; } } @@ -543,10 +659,10 @@ static void nsvg__deletePaths(NSVGpath* path) while (path) { NSVGpath *next = path->next; if (path->pts != NULL) { - FreePool(path->pts); + nsvg__delete(path->pts, "nsvg__deletePaths"_XS8); path->pts = NULL; } - FreePool(path); + nsvg__delete(path, "nsvg__deletePaths"_XS8); path = next; } } @@ -560,7 +676,7 @@ void nsvg__deleteFont(NSVGfont* font) if (font->missingGlyph) { // DBG("missing glyph=%s\n", font->missingGlyph->name); nsvg__deletePaths(font->missingGlyph->path); - FreePool(font->missingGlyph); + nsvg__delete(font->missingGlyph, "nsvg__deleteFont"_XS8); font->missingGlyph = NULL; } glyphs = font->glyphs; @@ -568,10 +684,10 @@ void nsvg__deleteFont(NSVGfont* font) // DBG(" glyph=%s\n", glyphs->name); next = glyphs->next; nsvg__deletePaths(glyphs->path); - FreePool(glyphs); + nsvg__delete(glyphs, "nsvg__deleteFont"_XS8); glyphs = next; } - FreePool(font); + nsvg__delete(font, "nsvg__deleteFont"_XS8); } static void nsvg__deletePaint(NSVGpaint* paint) @@ -582,7 +698,7 @@ static void nsvg__deletePaint(NSVGpaint* paint) if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT || paint->type == NSVG_PAINT_CONIC_GRADIENT) { - FreePool(paint->paint.gradient); + nsvg__delete(paint->paint.gradient, "nsvg__deletePaint"_XS8); paint->paint.gradient = NULL; } } @@ -593,9 +709,9 @@ static void nsvg__deleteGradientData(NSVGgradientData* grad) while (grad != NULL) { next = grad->next; if (grad->nstops > 0) { - FreePool(grad->stops); + nsvg__delete(grad->stops, "nsvg__deleteGradientData"_XS8); } - FreePool(grad); + nsvg__delete(grad, "nsvg__deleteGradientData"_XS8); grad = next; } } @@ -608,7 +724,7 @@ static void nsvg__deleteSymbols(NSVGsymbol* symbol) next = symbol->next; NSVGshape* shape = symbol->shapes; nsvg__deleteShapes(shape); - FreePool(symbol); + nsvg__delete(symbol, "nsvg__deleteSymbols"_XS8); symbol = next; } } @@ -625,17 +741,17 @@ void nsvg__deleteParser(NSVGparser* p) nsvgDelete(p->image); if (p->cpts > 0 && p->pts) { - FreePool(p->pts); + nsvg__delete(p->pts, "nsvg__deleteParser"_XS8); } for (i=0; iattr[i]); if (attr && attr->fontFace) { - FreePool(attr->fontFace); + nsvg__delete(attr->fontFace, "nsvg__deleteParser2"_XS8); attr->fontFace = NULL; } while (attr->group) { NSVGgroup* group = attr->group->next; - FreePool(attr->group); + nsvg__delete(attr->group, "nsvg__deleteParser3"_XS8); attr->group = group; } } @@ -647,7 +763,7 @@ static void nsvg__resetPath(NSVGparser* p) { p->npts = 0; if (p->cpts > 0 && p->pts) { - FreePool(p->pts); + nsvg__delete(p->pts, "nsvg__resetPath"_XS8); p->pts = NULL; p->cpts = 0; } @@ -660,11 +776,11 @@ static void nsvg__addPoint(NSVGparser* p, float x, float y) // DBG("npts=%d, cpts=%d\n", p->npts, p->cpts); if ((p->cpts == 0) || !p->pts) { p->cpts = 8; - p->pts = (float*)AllocatePool(16 * sizeof(float)); + p->pts = (float*)nsvg__alloc(16 * sizeof(float), "nsvg__addPoint"_XS8); } else { // DBG("reallocate\n"); p->cpts *= 2; - p->pts = (float*)ReallocatePool(p->cpts*sizeof(float), p->cpts*2*sizeof(float), p->pts); + p->pts = (float*)nsvg__realloc(p->cpts*sizeof(float), p->cpts*2*sizeof(float), p->pts, "nsvg__addPoint"_XS8); } if (!p->pts) return; @@ -810,7 +926,7 @@ static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id) static NSVGgradientLink* nsvg__createGradientLink(const char* id) { - NSVGgradientLink* grad = (NSVGgradientLink*)AllocateZeroPool(sizeof(NSVGgradientLink)); + NSVGgradientLink* grad = (NSVGgradientLink*)nsvg__alloczero(sizeof(NSVGgradientLink), "nsvg__createGradientLink"_XS8); if (grad == NULL) return NULL; strncpy(grad->id, id, 63); grad->id[63] = '\0'; @@ -856,7 +972,7 @@ static NSVGgradient* nsvg__createGradient(NSVGparser* p, NSVGshape* shape, NSVGg } if (stops == NULL) return NULL; // DumpFloat2("gradient final xform:", data->xform, 6); - grad = (NSVGgradient*)AllocateZeroPool(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1)); + grad = (NSVGgradient*)nsvg__alloczero(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1), "nsvg__createGradient"_XS8); if (grad == NULL) return NULL; // The shape width and height. if (data->units == NSVG_OBJECT_SPACE) { @@ -985,7 +1101,7 @@ static void nsvg__addShape(NSVGparser* p) if (p->plist == NULL /*&& !p->isText*/ ) return; - shape = (NSVGshape*)AllocateZeroPool(sizeof(NSVGshape)); + shape = (NSVGshape*)nsvg__alloczero(sizeof(NSVGshape), S8Printf("nsvg__addShape %s", attr->id)); if (shape == NULL) return; memcpy(shape->id, attr->id, sizeof shape->id); @@ -1010,10 +1126,10 @@ static void nsvg__addShape(NSVGparser* p) shape->clip.count = attr->clipPathCount; // if (shape->clip.count > 0) { -// shape->clip.index = (NSVGclipPathIndex*)AllocateCopyPool(attr->clipPathCount * sizeof(NSVGclipPathIndex), +// shape->clip.index = (NSVGclipPathIndex*)nsvg__alloccopy(attr->clipPathCount * sizeof(NSVGclipPathIndex), // p->clipPathStack); // if (shape->clip.index == NULL) { -// FreePool(shape); +// nsvg__delete(shape); // return; // } // } @@ -1034,9 +1150,9 @@ static void nsvg__addShape(NSVGparser* p) if (shape->fill.paint.gradientLink == NULL) { shape->fill.type = NSVG_PAINT_NONE; // if (shape->clip.index) { -// FreePool(shape->clip.index); +// nsvg__delete(shape->clip.index); // } - FreePool(shape); + nsvg__delete(shape, "nsvg__addShape"_XS8); return; } } else if (attr->hasFill == 3) { @@ -1063,9 +1179,9 @@ static void nsvg__addShape(NSVGparser* p) if (shape->stroke.paint.gradientLink == NULL) { shape->fill.type = NSVG_PAINT_NONE; // if (shape->clip.index) { -// FreePool(shape->clip.index); +// nsvg__delete(shape->clip.index); // } - FreePool(shape); + nsvg__delete(shape, "nsvg__addShape"_XS8); return; } } else if (attr->hasStroke == 3) { @@ -1110,7 +1226,7 @@ static void nsvg__addShape(NSVGparser* p) return; } -static void nsvg__addPath(NSVGparser* p, char closed) +static void nsvg__addPath(NSVGparser* p, char closed, const char* fromWhere) { // NSVGattrib* attr = nsvg__getAttr(p); NSVGpath* path = NULL; @@ -1127,13 +1243,13 @@ static void nsvg__addPath(NSVGparser* p, char closed) if ((p->npts % 3) != 1) return; - path = (NSVGpath*)AllocateZeroPool(sizeof(NSVGpath)); + path = (NSVGpath*)nsvg__alloczero(sizeof(NSVGpath), S8Printf("nsvg__addPath from %s", fromWhere)); if (path == NULL) { return; } - path->pts = (float*)AllocateZeroPool(p->npts*2*sizeof(float)); + path->pts = (float*)nsvg__alloczero(p->npts*2*sizeof(float), S8Printf("nsvg__addPath2 from %s", fromWhere)); if (path->pts == NULL) { - FreePool(path); + nsvg__delete(path, "nsvg__addPath3"_XS8); return; } path->closed = closed; @@ -1935,7 +2051,7 @@ static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* str static NSVGclipPath* nsvg__createClipPath(const char* name, int index) { - NSVGclipPath* clipPath = (NSVGclipPath*)AllocateZeroPool(sizeof(NSVGclipPath)); + NSVGclipPath* clipPath = (NSVGclipPath*)nsvg__alloczero(sizeof(NSVGclipPath), "nsvg__createClipPath"_XS8); if (clipPath == NULL) return NULL; strncpy(clipPath->id, name, 63); @@ -2074,7 +2190,7 @@ static int nsvg__parseAttr(NSVGparser* p, const char* name, char* value) } else if (strcmp(name, "font-size") == 0) { if (!attr->fontFace) { // DBG("font face=%d\n", sizeof(NSVGfont)); - attr->fontFace = (NSVGfont*)AllocateZeroPool(sizeof(NSVGfont)); + attr->fontFace = (NSVGfont*)nsvg__alloczero(sizeof(NSVGfont), "nsvg__parseAttr fontFace"_XS8); } attr->fontFace->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p)); } else if (strcmp(name, "clip-path") == 0) { @@ -2093,7 +2209,7 @@ static int nsvg__parseAttr(NSVGparser* p, const char* name, char* value) } else if (strcmp(name, "font-family") == 0) { if (!attr->fontFace) { // DBG("font face=%d\n", sizeof(NSVGfont)); - attr->fontFace = (NSVGfont*)AllocateZeroPool(sizeof(NSVGfont)); + attr->fontFace = (NSVGfont*)nsvg__alloczero(sizeof(NSVGfont), "nsvg__parseAttr fontFace2"_XS8); } if (attr->fontFace) { if (value[0] == 0x27) { //' @@ -2106,7 +2222,7 @@ static int nsvg__parseAttr(NSVGparser* p, const char* name, char* value) } } else if (strcmp(name, "font-weight") == 0) { if (!attr->fontFace) { - attr->fontFace = (NSVGfont*)AllocateZeroPool(sizeof(NSVGfont)); + attr->fontFace = (NSVGfont*)nsvg__alloczero(sizeof(NSVGfont), "nsvg__parseAttr fontFace3"_XS8); } if (attr->fontFace) { // char* Next = 0; @@ -2117,7 +2233,7 @@ static int nsvg__parseAttr(NSVGparser* p, const char* name, char* value) } else if (strcmp(name, "font-style") == 0) { DBG("attr=%s value=%s\n", name, value); if (!attr->fontFace) { - attr->fontFace = (NSVGfont*)AllocateZeroPool(sizeof(NSVGfont)); + attr->fontFace = (NSVGfont*)nsvg__alloczero(sizeof(NSVGfont), "nsvg__parseAttr fontFace4"_XS8); } if (strstr(value, "italic") != NULL) { DBG("it is italic\n"); @@ -2654,7 +2770,7 @@ static void nsvg__parsePath(NSVGparser* p, char** attr) // rargs = nsvg__getArgsPerElement(cmd); if (cmd == 'M' || cmd == 'm') { if (p->npts > 0) - nsvg__addPath(p, closedFlag); + nsvg__addPath(p, closedFlag, "nsvg__parsePath"); // Start new subpath. nsvg__resetPath(p); closedFlag = 0; @@ -2672,7 +2788,7 @@ static void nsvg__parsePath(NSVGparser* p, char** attr) cpx = p->pts[0]; cpy = p->pts[1]; cpx2 = cpx; cpy2 = cpy; - nsvg__addPath(p, closedFlag); + nsvg__addPath(p, closedFlag, "nsvg__parsePath"); } // Start new subpath. nsvg__resetPath(p); @@ -2690,7 +2806,7 @@ static void nsvg__parsePath(NSVGparser* p, char** attr) } // Commit path. if (p->npts) - nsvg__addPath(p, closedFlag); + nsvg__addPath(p, closedFlag, "nsvg__parsePath"); } } @@ -2741,7 +2857,7 @@ static void nsvg__parseRect(NSVGparser* p, char** attr) nsvg__lineTo(p, x, y+ry); nsvg__cubicBezTo(p, x, y+ry*(1-NSVG_KAPPA90), x+rx*(1-NSVG_KAPPA90), y, x+rx, y); } - nsvg__addPath(p, 1); + nsvg__addPath(p, 1, "parseRect"); nsvg__addShape(p); } } @@ -2800,7 +2916,7 @@ static void nsvg__parseUse(NSVGparser* p, char** dict) // DumpFloat2("use xform", xform, 6); if (ref) { - shape = (NSVGshape*)AllocateCopyPool(sizeof(NSVGshape), ref); + shape = (NSVGshape*)nsvg__alloccopy(sizeof(NSVGshape), ref, "nsvg__parseUse shape"_XS8); if (!shape) return; memcpy(shape->xform, &xform[0], sizeof(float)*6); shape->isSymbol = false; @@ -2814,7 +2930,7 @@ static void nsvg__parseUse(NSVGparser* p, char** dict) takeXformBounds(ref, &xform[0], shape->bounds); // DumpFloat2("used shape has bounds", shape->bounds, 4); } else if (refSym) { - shape = (NSVGshape*)AllocateZeroPool(sizeof(NSVGshape)); + shape = (NSVGshape*)nsvg__alloczero(sizeof(NSVGshape), "nsvg__parseUse shape2"_XS8); if (!shape) return; memcpy(shape->xform, xform, sizeof(float)*6); // nsvg__xformMultiply(shape->xform, &xform[0]); @@ -2926,7 +3042,7 @@ static void nsvg__parseText(NSVGparser* p, char** dict) int i; // DBG("text found\n"); - NSVGtext* text = (NSVGtext*)AllocateZeroPool(sizeof(NSVGtext)); + NSVGtext* text = (NSVGtext*)nsvg__alloczero(sizeof(NSVGtext), "nsvg__parseText"_XS8); if (!text) { return; } @@ -3004,7 +3120,7 @@ static void nsvg__parseText(NSVGparser* p, char** dict) fontSVG = fontsDB->font; //last added during parse file data text->font = fontSVG; } - FreePool(FileData); //after load + FreePool(FileData); //after load // don not use nsvg__delete because it's not allocated by nsvg__alloc... FileData = NULL; } else { // DBG("set embedded font\n"); @@ -3107,7 +3223,7 @@ static void nsvg__parseCircle(NSVGparser* p, char** attr) nsvg__cubicBezTo(p, cx-r*NSVG_KAPPA90, cy+r, cx-r, cy+r*NSVG_KAPPA90, cx-r, cy); nsvg__cubicBezTo(p, cx-r, cy-r*NSVG_KAPPA90, cx-r*NSVG_KAPPA90, cy-r, cx, cy-r); nsvg__cubicBezTo(p, cx+r*NSVG_KAPPA90, cy-r, cx+r, cy-r*NSVG_KAPPA90, cx+r, cy); - nsvg__addPath(p, 1); + nsvg__addPath(p, 1, "parseCircle"); nsvg__addShape(p); } } @@ -3136,7 +3252,7 @@ static void nsvg__parseEllipse(NSVGparser* p, char** attr) nsvg__cubicBezTo(p, cx-rx*NSVG_KAPPA90, cy+ry, cx-rx, cy+ry*NSVG_KAPPA90, cx-rx, cy); nsvg__cubicBezTo(p, cx-rx, cy-ry*NSVG_KAPPA90, cx-rx*NSVG_KAPPA90, cy-ry, cx, cy-ry); nsvg__cubicBezTo(p, cx+rx*NSVG_KAPPA90, cy-ry, cx+rx, cy-ry*NSVG_KAPPA90, cx+rx, cy); - nsvg__addPath(p, 1); + nsvg__addPath(p, 1, "nsvg__parseEllipse"); nsvg__addShape(p); } } @@ -3160,7 +3276,7 @@ static void nsvg__parseLine(NSVGparser* p, char** attr) nsvg__resetPath(p); nsvg__moveTo(p, x1, y1); nsvg__lineTo(p, x2, y2); - nsvg__addPath(p, 0); + nsvg__addPath(p, 0, "nsvg__parseLine"); nsvg__addShape(p); } @@ -3195,7 +3311,7 @@ static void nsvg__parsePoly(NSVGparser* p, char** attr, int closeFlag) } } - nsvg__addPath(p, (char)closeFlag); + nsvg__addPath(p, (char)closeFlag, "nsvg__parsePoly"); nsvg__addShape(p); } @@ -3240,7 +3356,7 @@ static void nsvg__parsePoly(NSVGparser* p, char** attr, int closeFlag) if (href == NULL) return; - shape = (NSVGshape*)AllocateZeroPool(sizeof(NSVGshape)); + shape = (NSVGshape*)nsvg__alloczero(sizeof(NSVGshape)); if (shape == NULL) return; memcpy(shape->id, attr->id, sizeof shape->id); @@ -3318,7 +3434,7 @@ static void parseImage(NSVGparser* p, char** dict) NewImage->FromPNG(tmpData, len); pt->image = (void *)NewImage; if (tmpData) { - FreePool(tmpData); + nsvg__delete(tmpData, "parseImage tmpData"_XS8); } } @@ -3339,7 +3455,7 @@ static void parsePattern(NSVGparser* p, char** dict) } } - pt = (decltype(pt))AllocateZeroPool(sizeof(NSVGpattern)); + pt = (decltype(pt))nsvg__alloczero(sizeof(NSVGpattern), "parsePattern"_XS8); AsciiStrCpyS(pt->id, 64, attr->id); pt->width = w; pt->height = h; @@ -3394,7 +3510,7 @@ static void nsvg__parseSVG(NSVGparser* p, char** attr) static void nsvg__parseGradient(NSVGparser* p, char** attr, char type) { int i; - NSVGgradientData* grad = (NSVGgradientData*)AllocateZeroPool(sizeof(NSVGgradientData)); + NSVGgradientData* grad = (NSVGgradientData*)nsvg__alloczero(sizeof(NSVGgradientData), "nsvg__parseGradient"_XS8); if (grad == NULL) return; //defaults grad->units = NSVG_USER_SPACE; //NSVG_OBJECT_SPACE; @@ -3498,11 +3614,11 @@ static void nsvg__parseGradientStop(NSVGparser* p, char** dict) nsize = sizeof(NSVGgradientStop) * grad->nstops; if (nsize == 0) { - grad->stops = (NSVGgradientStop*)AllocatePool(sizeof(NSVGgradientStop)); + grad->stops = (NSVGgradientStop*)nsvg__alloc(sizeof(NSVGgradientStop), "nsvg__parseGradientStop"_XS8); grad->nstops = 1; } else { grad->nstops++; - grad->stops = (NSVGgradientStop*)ReallocatePool(nsize, sizeof(NSVGgradientStop)*grad->nstops, grad->stops); + grad->stops = (NSVGgradientStop*)nsvg__realloc(nsize, sizeof(NSVGgradientStop)*grad->nstops, grad->stops, "nsvg__parseGradientStop"_XS8); } if (grad->stops == NULL) return; @@ -3529,7 +3645,7 @@ static void nsvg__parseSymbol(NSVGparser* p, char** dict) NSVGsymbol* symbol; NSVGattrib* curAttr = nsvg__getAttr(p); int i; - symbol = (NSVGsymbol*)AllocateZeroPool(sizeof(NSVGsymbol)); + symbol = (NSVGsymbol*)nsvg__alloczero(sizeof(NSVGsymbol), "nsvg__parseSymbol"_XS8); for (i = 0; dict[i]; i += 2) { if (strcmp(dict[i], "viewBox") == 0) { char* Next = 0; @@ -3557,7 +3673,7 @@ static void nsvg__parseGroup(NSVGparser* p, char** dict) return; } // DBG("parse group\n"); - group = (NSVGgroup*)AllocateZeroPool(sizeof(NSVGgroup)); + group = (NSVGgroup*)nsvg__alloczero(sizeof(NSVGgroup), "nsvg__parseGroup"_XS8); // if (curAttr->id[0] == '\0') //skip anonymous groups // return; @@ -3677,7 +3793,7 @@ static void nsvg__parseFont(NSVGparser* p, char** dict) return; } - font = (decltype(font))AllocateZeroPool(sizeof(*font)); + font = (decltype(font))nsvg__alloczero(sizeof(*font), "nsvg__parseFont"_XS8); for (i = 0; dict[i]; i += 2) { if (strcmp(dict[i], "horiz-adv-x") == 0) { @@ -3695,7 +3811,7 @@ static void nsvg__parseFont(NSVGparser* p, char** dict) } // DBG("found font id=%s family=%s\n", font->id, font->fontFamily); - NSVGfontChain* fontChain = (decltype(fontChain))AllocatePool(sizeof(*fontChain)); + NSVGfontChain* fontChain = (decltype(fontChain))nsvg__alloc(sizeof(*fontChain), "nsvg__parseFont fontChain"_XS8); fontChain->font = font; fontChain->next = fontsDB; p->font = font; @@ -3854,7 +3970,7 @@ static void nsvg__parseGlyph(NSVGparser* p, char** dict, XBool missing) p->plist = NULL; - glyph = (NSVGglyph*)AllocateZeroPool(sizeof(NSVGglyph)); + glyph = (NSVGglyph*)nsvg__alloczero(sizeof(NSVGglyph), "nsvg__parseGlyph"_XS8); if (!glyph) { return; } @@ -4088,7 +4204,7 @@ float addLetter(NSVGparser* p, CHAR16 letter, float x, float y, float scale, UIN return x; } - shape = (NSVGshape*)AllocateZeroPool(sizeof(NSVGshape)); + shape = (NSVGshape*)nsvg__alloczero(sizeof(NSVGshape), S8Printf("addLetter %lc (shape)", letter)); if (shape == NULL) return x; g = p->text->font->glyphs; @@ -4120,7 +4236,7 @@ float addLetter(NSVGparser* p, CHAR16 letter, float x, float y, float scale, UIN x1 += g->horizAdvX * scale; //user space } if (shape) { - FreePool(shape); + nsvg__delete(shape, "addLetter shape"_XS8); } return x1; } @@ -4264,7 +4380,7 @@ static void nsvg__content(void* ud, char* s) if (state == 1) { if (nsvg__isspace(c) || c == '{') { NSVGstyles* next = p->styles; - p->styles = (NSVGstyles*)AllocatePool(sizeof(NSVGstyles)); + p->styles = (NSVGstyles*)nsvg__alloc(sizeof(NSVGstyles), "nsvg__content"_XS8); p->styles->next = next; p->styles->name = nsvg__strndup(start, (size_t)(s - start)); //style->name=cls-1 p->styles->description = NULL; @@ -4302,7 +4418,7 @@ static void nsvg__assignGradients(NSVGparser* p, NSVGshape* shapes) NSVGgradientLink* link = shape->fill.paint.gradientLink; shape->fill.paint.gradient = nsvg__createGradient(p, shape, link, &shape->fill.type); if (link != NULL) { - FreePool(link); + nsvg__delete(link, "nsvg__assignGradients"_XS8); } if (shape->fill.paint.gradient == NULL) { shape->fill.type = NSVG_PAINT_NONE; @@ -4312,7 +4428,7 @@ static void nsvg__assignGradients(NSVGparser* p, NSVGshape* shapes) NSVGgradientLink* link = shape->stroke.paint.gradientLink; shape->stroke.paint.gradient = nsvg__createGradient(p, shape, link, &shape->stroke.type); if (link != NULL) { - FreePool(link); + nsvg__delete(link, "nsvg__assignGradients"_XS8); } if (shape->stroke.paint.gradient == NULL) { shape->stroke.type = NSVG_PAINT_NONE; @@ -4329,7 +4445,7 @@ static char *nsvg__strndup(const char *s, size_t n) if (n < len) len = n; - result = (char *)AllocateCopyPool(len + 1, s); + result = (char *)nsvg__alloccopy(len + 1, s, "nsvg__strndup"_XS8); if (!result) return 0; @@ -4490,7 +4606,7 @@ void nsvg__deleteShapes(NSVGshape* shape) nsvg__deletePaint(&shape->fill); nsvg__deletePaint(&shape->stroke); } - FreePool(shape); + nsvg__delete(shape, "nsvg__deleteShapes"_XS8); shape = snext; } } @@ -4515,10 +4631,10 @@ void nsvgDelete(NSVGimage* image) group = image->groups; while (group != NULL) { gnext = group->next; - FreePool(group); + nsvg__delete(group, "nsvgDelete group"_XS8); group = gnext; } - FreePool(image); + nsvg__delete(image, "nsvgDelete image"_XS8); } diff --git a/rEFIt_UEFI/libeg/nanosvg.h b/rEFIt_UEFI/libeg/nanosvg.h index 0e1daec49..43056851f 100644 --- a/rEFIt_UEFI/libeg/nanosvg.h +++ b/rEFIt_UEFI/libeg/nanosvg.h @@ -58,6 +58,10 @@ extern "C" { #define NSVG_MAX_ATTR 2048 #define NSVG_MAX_CLIP_PATHS 1024 // also note NSVGclipPathIndex +#define NANOSVG_MEMORY_ALLOCATION_TRACE +#ifdef JIEF_DEBUG +#define NANOSVG_MEMORY_ALLOCATION_TRACE_VERBOSE +#endif enum NSVGpaintType { NSVG_PAINT_NONE = 0, @@ -162,7 +166,7 @@ typedef struct NSVGgroup char id[kMaxIDLength]; struct NSVGgroup* parent; // Pointer to parent group or NULL struct NSVGgroup* next; // Pointer to next group or NULL - struct NSVGshape* shapeList; // list of shapes inside the group +// struct NSVGshape* xshapeList; // list of shapes inside the group int visibility; } NSVGgroup; @@ -440,6 +444,24 @@ typedef struct NSVGparser NSVGclipPathIndex clipPathStack[NSVG_MAX_CLIP_PATHS]; } NSVGparser; +#include "../cpp_foundation/XArray.h" +#include "../cpp_foundation/XObjArray.h" +extern XArray allocatedPtr; +extern XObjArray allocatedPtrMsg; + +#ifdef NANOSVG_MEMORY_ALLOCATION_TRACE +extern int nvsg__memoryallocation_verbose; +void* nsvg__alloc(UINTN size, const XString8& msg); +void* nsvg__alloczero(UINTN size, const XString8& msg); +void* nsvg__alloccopy(UINTN size, const void* ref, const XString8& msg); +void* nsvg__realloc(UINTN oldsize, UINTN newsize, void* ref, const XString8& msg); +void nsvg__delete(void* buffer, const XString8& msg); +size_t nsvg__nbDanglingPtr(); +void nsvg__outputDanglingPtr(); + +#endif + +bool isShapeInGroup(NSVGshape* shape, const char* groupName); //---