changeset 8798:20105469cefe draft

(svn r12536) -Codechange: some stack allocations were too large for NDS, so use the SmallStackSafeStackAlloc wrapper. Allocate on the stack by default and on the heap for NDS (or other devices that have a very small stack).
author rubidium <rubidium@openttd.org>
date Tue, 01 Apr 2008 21:12:51 +0000
parents 4e2e28b63412
children f94bd2d555c9
files src/core/alloc_func.hpp src/pathfind.cpp src/viewport.cpp
diffstat 3 files changed, 63 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/alloc_func.hpp
+++ b/src/core/alloc_func.hpp
@@ -107,9 +107,11 @@
 #else
 	/** Storing it on the heap */
 	T *data;
+	/** The length (in elements) of data in this allocator. */
+	size_t len;
 
 	/** Allocating the memory */
-	SmallStackSafeStackAlloc() : data(MallocT<T>(length)) {}
+	SmallStackSafeStackAlloc() : data(MallocT<T>(length)), len(length) {}
 	/** And freeing when it goes out of scope */
 	~SmallStackSafeStackAlloc() { free(data); }
 #endif
@@ -118,7 +120,26 @@
 	 * Gets a pointer to the data stored in this wrapper.
 	 * @return the pointer.
 	 */
-	operator T* () { return data; }
+	inline operator T* () { return data; }
+
+	/**
+	 * Gets a pointer to the data stored in this wrapper.
+	 * @return the pointer.
+	 */
+	inline T* operator -> () { return data; }
+
+	/**
+	 * Gets a pointer to the last data element stored in this wrapper.
+	 * @note needed because endof does not work properly for pointers.
+	 * @return the 'endof' pointer.
+	 */
+	inline T* EndOf() {
+#if !defined(__NDS__)
+		return endof(data);
+#else
+		return &data[len];
+#endif
+	}
 };
 
 #endif /* ALLOC_FUNC_HPP */
--- a/src/pathfind.cpp
+++ b/src/pathfind.cpp
@@ -17,6 +17,7 @@
 #include "depot.h"
 #include "tunnelbridge_map.h"
 #include "core/random_func.hpp"
+#include "core/alloc_func.hpp"
 #include "tunnelbridge.h"
 
 /* remember which tiles we have already visited so we don't visit them again. */
@@ -291,39 +292,38 @@
 
 void FollowTrack(TileIndex tile, uint16 flags, uint sub_type, DiagDirection direction, TPFEnumProc *enum_proc, TPFAfterProc *after_proc, void *data)
 {
-	TrackPathFinder tpf;
+	assert(IsValidDiagDirection(direction));
 
-	assert(direction < 4);
+	SmallStackSafeStackAlloc<TrackPathFinder, 1> tpf;
 
 	/* initialize path finder variables */
-	tpf.userdata = data;
-	tpf.enum_proc = enum_proc;
-	tpf.new_link = tpf.links;
-	tpf.num_links_left = lengthof(tpf.links);
+	tpf->userdata = data;
+	tpf->enum_proc = enum_proc;
+	tpf->new_link = tpf->links;
+	tpf->num_links_left = lengthof(tpf->links);
 
-	tpf.rd.cur_length = 0;
-	tpf.rd.depth = 0;
-	tpf.rd.last_choosen_track = INVALID_TRACK;
+	tpf->rd.cur_length = 0;
+	tpf->rd.depth = 0;
+	tpf->rd.last_choosen_track = INVALID_TRACK;
 
-	tpf.var2 = HasBit(flags, 15) ? 0x43 : 0xFF; // 0x8000
+	tpf->var2 = HasBit(flags, 15) ? 0x43 : 0xFF; // 0x8000
 
-	tpf.disable_tile_hash = HasBit(flags, 12);  // 0x1000
+	tpf->disable_tile_hash = HasBit(flags, 12);  // 0x1000
 
 
-	tpf.tracktype = (TransportType)(flags & 0xFF);
-	tpf.sub_type = sub_type;
+	tpf->tracktype = (TransportType)(flags & 0xFF);
+	tpf->sub_type = sub_type;
 
 	if (HasBit(flags, 11)) {
-		tpf.enum_proc(tile, data, INVALID_TRACKDIR, 0);
-		TPFMode2(&tpf, tile, direction);
+		tpf->enum_proc(tile, data, INVALID_TRACKDIR, 0);
+		TPFMode2(tpf, tile, direction);
 	} else {
 		/* clear the hash_heads */
-		memset(tpf.hash_head, 0, sizeof(tpf.hash_head));
-		TPFMode1(&tpf, tile, direction);
+		memset(tpf->hash_head, 0, sizeof(tpf->hash_head));
+		TPFMode1(tpf, tile, direction);
 	}
 
-	if (after_proc != NULL)
-		after_proc(&tpf);
+	if (after_proc != NULL) after_proc(tpf);
 }
 
 struct StackedItem {
@@ -820,18 +820,18 @@
 /** new pathfinder for trains. better and faster. */
 void NewTrainPathfind(TileIndex tile, TileIndex dest, RailTypes railtypes, DiagDirection direction, NTPEnumProc* enum_proc, void* data)
 {
-	NewTrackPathFinder tpf;
+	SmallStackSafeStackAlloc<NewTrackPathFinder, 1> tpf;
 
-	tpf.dest = dest;
-	tpf.userdata = data;
-	tpf.enum_proc = enum_proc;
-	tpf.tracktype = TRANSPORT_RAIL;
-	tpf.railtypes = railtypes;
-	tpf.maxlength = min(_patches.pf_maxlength * 3, 10000);
-	tpf.nstack = 0;
-	tpf.new_link = tpf.links;
-	tpf.num_links_left = lengthof(tpf.links);
-	memset(tpf.hash_head, 0, sizeof(tpf.hash_head));
+	tpf->dest = dest;
+	tpf->userdata = data;
+	tpf->enum_proc = enum_proc;
+	tpf->tracktype = TRANSPORT_RAIL;
+	tpf->railtypes = railtypes;
+	tpf->maxlength = min(_patches.pf_maxlength * 3, 10000);
+	tpf->nstack = 0;
+	tpf->new_link = tpf->links;
+	tpf->num_links_left = lengthof(tpf->links);
+	memset(tpf->hash_head, 0, sizeof(tpf->hash_head));
 
-	NTPEnum(&tpf, tile, direction);
+	NTPEnum(tpf, tile, direction);
 }
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -27,11 +27,15 @@
 #include "player_func.h"
 #include "settings_type.h"
 #include "station_func.h"
+#include "core/alloc_func.hpp"
 
 #include "table/sprites.h"
 #include "table/strings.h"
 
-#define VIEWPORT_DRAW_MEM (65536 * 2)
+enum {
+	VIEWPORT_DRAW_MEM = (65536 * 2),
+	PARENT_LIST_SIZE  = 6144,
+};
 
 PlaceProc *_place_proc;
 Point _tile_fract_coords;
@@ -1541,8 +1545,8 @@
 	int y;
 	DrawPixelInfo *old_dpi;
 
-	byte mem[VIEWPORT_DRAW_MEM];
-	ParentSpriteToDraw *parent_list[6144];
+	SmallStackSafeStackAlloc<byte, VIEWPORT_DRAW_MEM> mem;
+	SmallStackSafeStackAlloc<ParentSpriteToDraw*, PARENT_LIST_SIZE> parent_list;
 
 	_cur_vd = &vd;
 
@@ -1566,9 +1570,9 @@
 	vd.dpi.dst_ptr = BlitterFactoryBase::GetCurrentBlitter()->MoveTo(old_dpi->dst_ptr, x - old_dpi->left, y - old_dpi->top);
 
 	vd.parent_list = parent_list;
-	vd.eof_parent_list = endof(parent_list);
+	vd.eof_parent_list = parent_list.EndOf();
 	vd.spritelist_mem = mem;
-	vd.eof_spritelist_mem = endof(mem) - sizeof(LARGEST_SPRITELIST_STRUCT);
+	vd.eof_spritelist_mem = mem.EndOf() - sizeof(LARGEST_SPRITELIST_STRUCT);
 	vd.last_string = &vd.first_string;
 	vd.first_string = NULL;
 	vd.last_tile = &vd.first_tile;