Skip to content

Commit 650608f

Browse files
bulk88mauke
authored andcommitted
de-layer Perlhost.h's 3 Malloc() classed + Cwd class
-Perl's primary malloc pool (per interp, never ithread shared), doesnt need CS mutexes, the refcounting/multiple my_perl owners infrastruture, etc. Inline the IPerlMem/VPerLMem class/struct direct into CPerlHost class. Less ptr derefs at runtime. Saves memory, because no malloc header. And remove the 0x24 ??? bytes on x86-32 CS/mutex struct. -Use retval of libc's memset(), saves a non-vol reg push/pop/saving cycle. ZeroMemory() has void retval. Lack of a Calloc() API in VMem.h is for another time. -"virtual int Chdir(const char *dirname);" remove virtual tag. It is unused ptr indirection. Also the secret C++ vtable ptr im CPerlHost objs is now gone. -inline VDir obj into CPerlHost, VDir *s are not shared between interps. -Sort machine type integer members of CPerlHost class by size. Remove Alignment holes. -Speedup win32_checkTLS(), win32_checkTLS() is probably redundant outside -DDEBUGGING nowadays, it was added in commit 222c300 1/13/2002 10:37:48 AM Win32 fixes: - vmem.h hack to handle free-by-wrong-thread after eval "". still will leave it in for now, just optimize it instead. I benchmarked, 10000x calls to Perl_get_context() in a loop. Retval ignored, is 126 us (microsec). 10000x calls to GetCurrentThreadId(), is 34 us.
1 parent 48bda52 commit 650608f

File tree

7 files changed

+277
-79
lines changed

7 files changed

+277
-79
lines changed

win32/perlhost.h

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@
1515
#include <signal.h>
1616
#include <wchar.h>
1717
#include "iperlsys.h"
18+
19+
#include "vmem.h"
20+
21+
#define CRT_ALLOC_BASE
1822
#include "vmem.h"
23+
#undef CRT_ALLOC_BASE
24+
1925
#include "vdir.h"
2026

2127
#ifndef WC_NO_BEST_FIT_CHARS
@@ -38,6 +44,7 @@ class CPerlHost
3844
const struct IPerlProc** ppProc);
3945
CPerlHost(CPerlHost& host);
4046
~CPerlHost(void);
47+
VMEM_H_NEW_OP;
4148

4249
static CPerlHost* IPerlMem2Host(const struct IPerlMem** piPerl);
4350
static CPerlHost* IPerlMemShared2Host(const struct IPerlMem** piPerl);
@@ -56,20 +63,20 @@ class CPerlHost
5663

5764
/* IPerlMem */
5865
/* Locks provided but should be unnecessary as this is private pool */
59-
inline void* Malloc(size_t size) { return m_pVMem->Malloc(size); };
60-
inline void* Realloc(void* ptr, size_t size) { return m_pVMem->Realloc(ptr, size); };
61-
inline void Free(void* ptr) { m_pVMem->Free(ptr); };
66+
inline void* Malloc(size_t size) { return m_VMem.Malloc(size); };
67+
inline void* Realloc(void* ptr, size_t size) { return m_VMem.Realloc(ptr, size); };
68+
inline void Free(void* ptr) { m_VMem.Free(ptr); };
6269
inline void* Calloc(size_t num, size_t size)
6370
{
6471
size_t count = num*size;
6572
void* lpVoid = Malloc(count);
6673
if (lpVoid)
67-
ZeroMemory(lpVoid, count);
74+
lpVoid = memset(lpVoid, 0, count);
6875
return lpVoid;
6976
};
70-
inline void GetLock(void) { m_pVMem->GetLock(); };
71-
inline void FreeLock(void) { m_pVMem->FreeLock(); };
72-
inline int IsLocked(void) { return m_pVMem->IsLocked(); };
77+
inline void GetLock(void) { m_VMem.GetLock(); };
78+
inline void FreeLock(void) { m_VMem.FreeLock(); };
79+
inline int IsLocked(void) { return m_VMem.IsLocked(); };
7380

7481
/* IPerlMemShared */
7582
/* Locks used to serialize access to the pool */
@@ -103,7 +110,7 @@ class CPerlHost
103110
size_t count = num*size;
104111
void* lpVoid = MallocShared(count);
105112
if (lpVoid)
106-
ZeroMemory(lpVoid, count);
113+
lpVoid = memset(lpVoid, 0, count);
107114
return lpVoid;
108115
};
109116

@@ -122,7 +129,7 @@ class CPerlHost
122129
size_t count = num*size;
123130
void* lpVoid = MallocParse(count);
124131
if (lpVoid)
125-
ZeroMemory(lpVoid, count);
132+
lpVoid = memset(lpVoid, 0, count);
126133
return lpVoid;
127134
};
128135

@@ -137,7 +144,7 @@ class CPerlHost
137144
*len = strlen(e);
138145
return e;
139146
}
140-
void* CreateChildEnv(void) { return CreateLocalEnvironmentStrings(*m_pvDir); };
147+
void* CreateChildEnv(void) { return CreateLocalEnvironmentStrings(m_vDir); };
141148
void FreeChildEnv(void* pStr) { FreeLocalEnvironmentStrings((char*)pStr); };
142149
char* GetChildDir(void);
143150
void FreeChildDir(char* pStr);
@@ -166,7 +173,7 @@ class CPerlHost
166173
public:
167174

168175
/* IPerlDIR */
169-
virtual int Chdir(const char *dirname);
176+
int Chdir(const char *dirname);
170177

171178
/* IPerllProc */
172179
void Abort(void);
@@ -176,9 +183,10 @@ class CPerlHost
176183
int Execv(const char *cmdname, const char *const *argv);
177184
int Execvp(const char *cmdname, const char *const *argv);
178185

186+
inline VMem* GetMem(void) { return (VMem* )&m_VMem; };
179187
inline VMem* GetMemShared(void) { m_pVMemShared->AddRef(); return m_pVMemShared; };
180188
inline VMem* GetMemParse(void) { m_pVMemParse->AddRef(); return m_pVMemParse; };
181-
inline VDir* GetDir(void) { return m_pvDir; };
189+
inline VDir* GetDir(void) { return &m_vDir; };
182190

183191
public:
184192

@@ -192,22 +200,23 @@ class CPerlHost
192200
const struct IPerlSock* m_pHostperlSock;
193201
const struct IPerlProc* m_pHostperlProc;
194202

195-
inline char* MapPathA(const char *pInName) { return m_pvDir->MapPathA(pInName); };
196-
inline WCHAR* MapPathW(const WCHAR *pInName) { return m_pvDir->MapPathW(pInName); };
203+
inline char* MapPathA(const char *pInName) { return m_vDir.MapPathA(pInName); };
204+
inline WCHAR* MapPathW(const WCHAR *pInName) { return m_vDir.MapPathW(pInName); };
205+
inline operator VDir* () { return GetDir(); };
197206
protected:
198-
199-
VDir* m_pvDir;
200-
VMem* m_pVMem;
207+
VMemNL m_VMem;
201208
VMem* m_pVMemShared;
202209
VMem* m_pVMemParse;
203210

204-
DWORD m_dwEnvCount;
205211
LPSTR* m_lppEnvList;
212+
DWORD m_dwEnvCount;
206213
BOOL m_bTopLevel; // is this a toplevel host?
207214
static long num_hosts;
208215
public:
209216
inline int LastHost(void) { return num_hosts == 1L; };
210217
struct interpreter *host_perl;
218+
protected:
219+
VDir m_vDir;
211220
};
212221

213222
long CPerlHost::num_hosts = 0L;
@@ -2110,12 +2119,11 @@ CPerlHost::CPerlHost(void)
21102119
{
21112120
/* Construct a host from scratch */
21122121
InterlockedIncrement(&num_hosts);
2113-
m_pvDir = new VDir();
2114-
m_pVMem = new VMem();
2122+
21152123
m_pVMemShared = new VMem();
21162124
m_pVMemParse = new VMem();
21172125

2118-
m_pvDir->Init(NULL, m_pVMem);
2126+
m_vDir.Init(NULL);
21192127

21202128
m_dwEnvCount = 0;
21212129
m_lppEnvList = NULL;
@@ -2150,12 +2158,11 @@ CPerlHost::CPerlHost(const struct IPerlMem** ppMem, const struct IPerlMem** ppMe
21502158
const struct IPerlProc** ppProc)
21512159
{
21522160
InterlockedIncrement(&num_hosts);
2153-
m_pvDir = new VDir(0);
2154-
m_pVMem = new VMem();
2161+
21552162
m_pVMemShared = new VMem();
21562163
m_pVMemParse = new VMem();
21572164

2158-
m_pvDir->Init(NULL, m_pVMem);
2165+
m_vDir.Init(NULL, 0);
21592166

21602167
m_dwEnvCount = 0;
21612168
m_lppEnvList = NULL;
@@ -2177,13 +2184,12 @@ CPerlHost::CPerlHost(CPerlHost& host)
21772184
{
21782185
/* Construct a host from another host */
21792186
InterlockedIncrement(&num_hosts);
2180-
m_pVMem = new VMem();
2187+
21812188
m_pVMemShared = host.GetMemShared();
21822189
m_pVMemParse = host.GetMemParse();
21832190

21842191
/* duplicate directory info */
2185-
m_pvDir = new VDir(0);
2186-
m_pvDir->Init(host.GetDir(), m_pVMem);
2192+
m_vDir.Init(host.GetDir(), 0);
21872193

21882194
m_pHostperlMem = &perlMem;
21892195
m_pHostperlMemShared = &perlMemShared;
@@ -2210,10 +2216,10 @@ CPerlHost::~CPerlHost(void)
22102216
{
22112217
Reset();
22122218
InterlockedDecrement(&num_hosts);
2213-
delete m_pvDir;
2219+
//delete m_vDir;
22142220
m_pVMemParse->Release();
22152221
m_pVMemShared->Release();
2216-
m_pVMem->Release();
2222+
//m_VMem.Release();
22172223
}
22182224

22192225
LPSTR
@@ -2360,7 +2366,7 @@ CPerlHost::GetChildDir(void)
23602366
size_t length;
23612367

23622368
Newx(ptr, MAX_PATH+1, char);
2363-
m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr);
2369+
m_vDir.GetCurrentDirectoryA(MAX_PATH+1, ptr);
23642370
length = strlen(ptr);
23652371
if (length > 3) {
23662372
if ((ptr[length-1] == '\\') || (ptr[length-1] == '/'))
@@ -2546,11 +2552,19 @@ CPerlHost::Chdir(const char *dirname)
25462552
errno = ENOENT;
25472553
return -1;
25482554
}
2549-
ret = m_pvDir->SetCurrentDirectoryA((char*)dirname);
2555+
ret = m_vDir.SetCurrentDirectoryA((char*)dirname);
25502556
if(ret < 0) {
25512557
errno = ENOENT;
25522558
}
25532559
return ret;
25542560
}
25552561

2562+
static inline VMemNL * VDToVM(VDir * pvd) {
2563+
VDir * vd = (VDir *)pvd;
2564+
size_t p_szt = ((size_t)vd)-((size_t)((CPerlHost*)NULL)->GetDir());
2565+
CPerlHost * cph = (CPerlHost*)p_szt;
2566+
VMemNL * vm = cph->GetMem();
2567+
return vm;
2568+
}
2569+
25562570
#endif /* ___PerlHost_H___ */

win32/perllib.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,21 @@ xs_init(pTHX)
4949
void
5050
win32_checkTLS(PerlInterpreter *host_perl)
5151
{
52-
dTHX;
53-
if (host_perl != my_perl) {
54-
int *nowhere = NULL;
55-
abort();
52+
/* GCurThdId() is lightweight, but b/c of the ctrl-c/signals sometimes firing
53+
in other random WinOS threads, that make the TIDs go out of sync.
54+
This isn't always an error, although high chance of a SEGV in the next
55+
couple milliseconds b/c of "Day 1 of Win32 port" Ctrl-C vs Perl bugs.
56+
Google it for details. So this code, if TIDs don't match, do the full heavy
57+
TlsGetValue() + misc fn calls. Then resync TIDs to keep this fast for
58+
future calls to this fn. */
59+
DWORD tid = GetCurrentThreadId();
60+
if(tid != host_perl->Isys_intern.cur_tid) {
61+
dTHX; /* heavyweight */
62+
if (host_perl != my_perl) {
63+
int *nowhere = NULL;
64+
abort();
65+
}
66+
host_perl->Isys_intern.cur_tid = tid;
5667
}
5768
}
5869

win32/vdir.h

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@ class VDir
2323
VDir(int bManageDir = 1);
2424
~VDir() {};
2525

26-
void Init(VDir* pDir, VMem *pMem);
26+
VMEM_H_NEW_OP;
27+
void Init(VDir* pDirCloneFrom);
28+
void Init(VDir* pDirCloneFrom, int bManageDir);
2729
void SetDefaultA(char const *pDefault);
2830
void SetDefaultW(WCHAR const *pDefault);
2931
char* MapPathA(const char *pInName);
3032
WCHAR* MapPathW(const WCHAR *pInName);
31-
int SetCurrentDirectoryA(char *lpBuffer);
33+
/* CPerlHost::Chdir() is the only caller */
34+
inline int SetCurrentDirectoryA(char *lpBuffer);
3235
int SetCurrentDirectoryW(WCHAR *lpBuffer);
3336
inline int GetDefault(void) { return nDefault; };
3437

@@ -116,36 +119,52 @@ class VDir
116119
return (chr | 0x20)-'a';
117120
};
118121

119-
VMem *pMem;
120-
int nDefault, bManageDirectory;
121-
char *dirTableA[driveCount];
122-
char szLocalBufferA[MAX_PATH+1];
122+
/* Former "VMem *" member, just C-ptr-cast the VDir * to a CPerlHost *
123+
and get the "VMem *" directly vs 2 copies of the ptr. */
124+
#define pMem VDToVM(this)
125+
123126
WCHAR *dirTableW[driveCount];
127+
char *dirTableA[driveCount];
128+
int nDefault;
129+
130+
inline void * ZeroMemStart(void) {return (void *)dirTableW;};
131+
inline size_t ZeroMemSize(void) {
132+
return ((size_t)&nDefault)+sizeof(nDefault)-((size_t)dirTableW);
133+
};
134+
124135
WCHAR szLocalBufferW[MAX_PATH+1];
136+
char szLocalBufferA[MAX_PATH+1];
137+
bool bManageDirectory;
138+
125139
};
126140

141+
static inline VMemNL * VDToVM(VDir * vd);
127142

128143
VDir::VDir(int bManageDir /* = 1 */)
129144
{
130-
nDefault = 0;
145+
/* combine all fields needed Nulling into 1 call */
146+
memset(ZeroMemStart(), 0, ZeroMemSize());
147+
bManageDirectory = bManageDir;
148+
}
149+
150+
void VDir::Init(VDir* pDirCloneFrom, int bManageDir)
151+
{
131152
bManageDirectory = bManageDir;
132-
memset(dirTableA, 0, sizeof(dirTableA));
133-
memset(dirTableW, 0, sizeof(dirTableW));
153+
VDir::Init(pDirCloneFrom);
134154
}
135155

136-
void VDir::Init(VDir* pDir, VMem *p)
156+
void VDir::Init(VDir* pDirCloneFrom)
137157
{
138158
int index;
139159

140-
pMem = p;
141-
if (pDir) {
160+
if (pDirCloneFrom) {
142161
for (index = 0; index < driveCount; ++index) {
143-
SetDirW(pDir->GetDirW(index), index);
162+
SetDirW(pDirCloneFrom->GetDirW(index), index);
144163
}
145-
nDefault = pDir->GetDefault();
164+
nDefault = pDirCloneFrom->GetDefault();
146165
}
147166
else {
148-
int bSave = bManageDirectory;
167+
bool bSave = bManageDirectory;
149168
DWORD driveBits = GetLogicalDrives();
150169

151170
bManageDirectory = 0;

0 commit comments

Comments
 (0)