From d986ad90655708d4ec56d4e667f92b931aeaa4b8 Mon Sep 17 00:00:00 2001
From: pompolic <pompolic@special-circumstanc.es>
Date: Wed, 30 Nov 2022 20:52:54 +0100
Subject: [PATCH] (WIP) Checking allocation sizes at h_do_parse return

---
 gdb-port/parser.py          |  3 ++-
 gdb-port/top-level-parse.py | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/gdb-port/parser.py b/gdb-port/parser.py
index d3f5599..0455296 100644
--- a/gdb-port/parser.py
+++ b/gdb-port/parser.py
@@ -3,6 +3,7 @@ class Parser:
 		self.name = name
 		self.address = address
 		self.bytes_used = {}
+		self.bytes_used_from_hammer_stats = {} # TODO: once breakpoints vs detailed are exclusive, this should be removed
 
 	def name_parser(self, name):
 		self.name = name
@@ -26,7 +27,7 @@ class Parser:
 		if arena is None:
 			return self.bytes_used
 		else:
-			return self.bytes_used.setdefault(arena, 0) # TODO: getdefault
+			return self.bytes_used.setdefault(arena, 0)
 
 	def __str__(self):
 		return "(" + str(self.name) + ", " + hex(self.address) + ")"
diff --git a/gdb-port/top-level-parse.py b/gdb-port/top-level-parse.py
index 5213905..4f2a141 100644
--- a/gdb-port/top-level-parse.py
+++ b/gdb-port/top-level-parse.py
@@ -19,6 +19,16 @@ class TopLevelParse:
 		self.vt_types = None
 		self.parser_decombinator = None
 
+		# If available, extracting the allocated bytes at h_do_parse entry/exit
+		# TODO: doing it at h_do_parse gets a list of cumulative allocation sizes
+		# alloc belonging to only the function in question is calculated by
+		# tot_alloc[n] = alloc[n] - alloc[n+1]
+		# TODO: cumulative vs total
+		# TODO: could be a parserstack attribute
+		self.bytes_at_enter = []
+		self.cumulative_byte_differences = []
+		self.total_byte_differences = []
+
 		# Counts stack pushes/pops to determine if stopping is needed for hammer-parse-after-apply
 		self.ast_stack_index = None
 		# Holds a reference to the relevant parser stack
@@ -53,6 +63,10 @@ class TopLevelParse:
 	# TODO: arena parameter is useless
 	def enter_h_do_parse(self, parse_state, arena, parser):
 		parser_stack = self.peek_parserstack()
+		#if self.memory_stat_method == HammerMemoryStatisticsMethod.DETAILED_ARENA_STATS
+		if self.extended_arena_stats_available(): # DEBUG
+			self.bytes_at_enter.append(arena['arena_malloc_bytes'])
+
 		try:
 			parser_obj = self.parser_objs[parser]
 		except KeyError:
@@ -70,6 +84,11 @@ class TopLevelParse:
 		# If other backends are supported, this might change to pushing/popping the stack in h_do_parse()
 		self.h_do_parse_parser = parser_obj # Restore the "current" parser, otherwise it'll show the parser h_do_parse() was last called with on the GUI and backtrace
 
+		#if self.memory_stat_method == HammerMemoryStatisticsMethod.DETAILED_ARENA_STATS
+		if self.extended_arena_stats_available(): # DEBUG
+			newbytes = parse_state['arena']['arena_malloc_bytes']
+			self.cumulative_byte_differences.insert(0, newbytes - self.bytes_at_enter[-(len(self.cumulative_byte_differences)+1)] # TODO: consistency. this is the third way of answering the question, "how deep are we in the stack"
+
 	# Called from h_do_parse()'s handler, at which point we know the addresses of the state and arena
 	def first_h_do_parse_after_packrat_parse(self, parse_state, arena):
 		parser_stack = self.peek_parserstack()
-- 
GitLab