Skip to content

Commit 6545943

Browse files
authored
Merge pull request #488 from pharo-project/feat/permSpace
Adding Support for PermSpace
2 parents 7d7f8d3 + 419f4fc commit 6545943

File tree

149 files changed

+8829
-3947
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+8829
-3947
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ set(APPNAME "Pharo" CACHE STRING "VM Application name"
4141
set(FLAVOUR "CoInterpreter" CACHE STRING "The kind of VM to generate. Possible values: StackVM, CoInterpreter")
4242
set(PHARO_LIBRARY_PATH "@executable_path/Plugins" CACHE STRING "The RPATH to use in the build")
4343
set(ICEBERG_DEFAULT_REMOTE "scpUrl" CACHE STRING "If Iceberg uses HTTPS (httpsUrl) or tries first with SSH (scpUrl)")
44+
set(IMAGE_FORMAT "SpurFormat" CACHE STRING "Image Format to use in the builtVM (SpurFormat / ComposedFormat)")
4445

4546
if(VERBOSE_BUILD)
4647
set(CMAKE_VERBOSE_MAKEFILE TRUE)
@@ -335,6 +336,7 @@ add_compile_options(
335336
-Wno-unused-local-typedef
336337
-Wno-incompatible-pointer-types
337338
-Wno-shift-negative-value
339+
-Wno-unknown-warning-option
338340
)
339341

340342

Jenkinsfile

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,18 @@ def recordCygwinVersions(buildDirectory){
103103
archiveArtifacts artifacts: "${buildDirectory}/cygwinVersions.txt"
104104
}
105105

106-
def runBuild(platformName, configuration, headless = true){
106+
def runBuild(platformName, configuration, headless = true, someAdditionalParameters = ""){
107107
cleanWs()
108108

109109
def platform = headless ? platformName : "${platformName}-stockReplacement"
110110
def buildDirectory = headless ? "build" :"build-stockReplacement"
111-
def additionalParameters = ""
111+
def additionalParameters = someAdditionalParameters
112112

113-
additionalParameters += headless ? "" : "-DALWAYS_INTERACTIVE=1 "
114-
additionalParameters += isRelease() ? "-DBUILD_IS_RELEASE=ON " : "-DBUILD_IS_RELEASE=OFF "
113+
additionalParameters += headless ? "" : " -DALWAYS_INTERACTIVE=1 "
114+
additionalParameters += isRelease() ? " -DBUILD_IS_RELEASE=ON " : " -DBUILD_IS_RELEASE=OFF "
115115

116116
if(configuration == 'StackVM'){
117-
additionalParameters += "-DFEATURE_MESSAGE_COUNT=TRUE "
117+
additionalParameters += " -DFEATURE_MESSAGE_COUNT=TRUE "
118118
platform = "${platformName}-StackVM"
119119
buildDirectory = "build-StackVM"
120120
}
@@ -131,16 +131,20 @@ def runBuild(platformName, configuration, headless = true){
131131
recordCygwinVersions(buildDirectory)
132132
runInCygwin "cd ${buildDirectory} && cmake -DFLAVOUR=${configuration} ${additionalParameters} -DPHARO_DEPENDENCIES_PREFER_DOWNLOAD_BINARIES=TRUE ../repository -DICEBERG_DEFAULT_REMOTE=httpsUrl"
133133
runInCygwin "cd ${buildDirectory} && VERBOSE=1 make install package"
134+
runInCygwin "mkdir -p artifacts-${platformName} && cp -a ${buildDirectory}/build/packages/* artifacts-${platformName}/"
134135
}else{
135136
cmakeBuild generator: "Unix Makefiles", cmakeArgs: "-DFLAVOUR=${configuration} ${additionalParameters} -DPHARO_DEPENDENCIES_PREFER_DOWNLOAD_BINARIES=TRUE -DICEBERG_DEFAULT_REMOTE=httpsUrl", sourceDir: "repository", buildDir: "${buildDirectory}", installation: "InSearchPath"
136137
dir("${buildDirectory}"){
137138
shell "VERBOSE=1 make install package"
138139
}
140+
shell "mkdir -p artifacts-${platformName} && cp -a ${buildDirectory}/build/packages/* artifacts-${platformName}/"
139141
}
140142

141143
stash excludes: '_CPack_Packages', includes: "${buildDirectory}/build/packages/*", name: "packages-${platform}-${configuration}"
142144
stash includes: "repository/scripts/*", name: "scripts"
143145
archiveArtifacts artifacts: "${buildDirectory}/build/packages/*", excludes: '_CPack_Packages'
146+
archiveArtifacts artifacts: "artifacts-${platformName}/*", excludes: '_CPack_Packages'
147+
144148
}
145149
}
146150

@@ -197,6 +201,10 @@ def runUnitTests(platform){
197201
shell "PHARO_CI_TESTING_ENVIRONMENT=true ./vm/Contents/MacOS/Pharo --headless --logLevel=4 ./image/VMMaker.image test --junit-xml-output 'VMMakerTests'"
198202
shell "PHARO_CI_TESTING_ENVIRONMENT=true ./vm/Contents/MacOS/Pharo --headless --logLevel=4 ./image/VMMaker.image test --junit-xml-output 'Slang-Tests'"
199203
}
204+
205+
shell "zip ./VMMaker-Image.zip ./image/VMMaker.*"
206+
archiveArtifacts artifacts: 'VMMaker-Image.zip'
207+
200208
// Stop if tests fail
201209
// Archive xml reports either case
202210
try {
@@ -465,6 +473,9 @@ try{
465473
timeout(30){
466474
runBuild(platform, "StackVM")
467475
}
476+
timeout(30){
477+
runBuild("${platform}-ComposedFormat", "CoInterpreter", true, " -DIMAGE_FORMAT=ComposedFormat ")
478+
}
468479
timeout(30){
469480
// Only build the Stock replacement version in the main branch
470481
if(isMainBranch()){

cmake/vmmaker.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ if(GENERATE_SOURCES)
139139
#Custom command that generates the vm source code from VMMaker into the generated folder
140140
add_custom_command(
141141
OUTPUT ${VMSOURCEFILES} ${PLUGIN_GENERATED_FILES}
142-
COMMAND ${VMMAKER_VM} --headless ${VMMAKER_IMAGE} --no-default-preferences eval \"PharoVMMaker generate: \#\'${FLAVOUR}\' outputDirectory: \'${GENERATED_SOURCE_DIR}\'\"
142+
COMMAND ${VMMAKER_VM} --headless ${VMMAKER_IMAGE} --no-default-preferences eval \"PharoVMMaker generate: \#\'${FLAVOUR}\' outputDirectory: \'${CMAKE_CURRENT_BINARY_DIR_TO_OUT}\' imageFormat: \'${IMAGE_FORMAT}\'\"
143143
DEPENDS vmmaker ${VMMAKER_IMAGE} ${VMMAKER_VM}
144144
COMMENT "Generating VM files for flavour: ${FLAVOUR}")
145145

extracted/vm/include/common/sq.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
* If the attempt fails, answer null. If the attempt succeeds, answer the
5858
* start of the region and assign its size through asp.
5959
*/
60-
extern void *sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto(sqInt sz, void *minAddr, sqInt *asp);
6160
extern void sqDeallocateMemorySegmentAtOfSize(void *addr, sqInt sz);
6261
#endif /* SPURVM */
6362
/* Platform-dependent memory size adjustment macro. */
@@ -497,7 +496,7 @@ sqInt ioDisableImageWrite(void);
497496

498497
#include "pharovm/imageAccess.h"
499498

500-
size_t readImageFromFileStartingAt(sqImageFile f, squeakFileOffsetType imageOffset);
499+
sqInt readImageNamed(char* fileName);
501500

502501
/* Clipboard (cut/copy/paste). */
503502
sqInt clipboardSize(void);

extracted/vm/src/win/sqWin32SpurAlloc.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#define EXCEPTION_WRONG_ACCESS EXCEPTION_EXECUTE_HANDLER
2323
#endif
2424

25+
void *
26+
sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto(sqInt size, void *minAddress, sqInt *allocatedSizePointer);
27+
2528
LONG CALLBACK sqExceptionFilter(LPEXCEPTION_POINTERS exp)
2629
{
2730
/* always wrong access - we handle memory differently now */
@@ -86,12 +89,7 @@ sqAllocateMemory(usqInt minHeapSize, usqInt desiredHeapSize, usqInt desiredBaseA
8689

8790
alloc = sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto
8891
(roundUpToPage(desiredHeapSize), address, &allocBytes);
89-
if (!alloc) {
90-
exit(errno);
91-
sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Error:"),
92-
TEXT("sqAllocateMemory: initial alloc failed!\n"));
93-
exit(1);
94-
}
92+
9593
return alloc;
9694
}
9795

@@ -156,6 +154,7 @@ sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto(sqInt size, void *minAddress
156154
continue;
157155
}
158156
alloc = VirtualAlloc(address, bytes, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
157+
159158
/* For some reason (large page support?) we can ask for a page-aligned
160159
* address such as 0xNNNNf000 but VirtualAlloc will answer 0xNNNN0000.
161160
* So accept allocs above minAddress rather than allocs above address
@@ -168,9 +167,8 @@ sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto(sqInt size, void *minAddress
168167
return alloc;
169168
}
170169
if (!alloc) {
171-
DWORD lastError = GetLastError();
172-
logWarn("Unable to VirtualAlloc committed memory at desired address (%lld bytes requested at %p, above %p), Error: %lu\n",
173-
bytes, address, minAddress, lastError);
170+
logWarn("Unable to VirtualAlloc committed memory at desired address (%lld bytes requested at %p, above %p)", bytes, address, minAddress);
171+
logErrorFromGetLastError("Unable to VirtualAlloc committed memory at desired address");
174172
return 0;
175173
}
176174
/* VirtualAlloc answered a mapping well away from where Spur prefers.

include/pharovm/parameters/parameters.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ typedef struct VMParameters_
120120
//The eden size (This is the space used to allocate new objects).
121121
long long edenSize;
122122

123+
//The minimal Permanent Space Size
124+
long long minPermSpaceSize;
125+
123126
// FIXME: Why passing this is needed when we have the separated vectors?
124127
int processArgc;
125128
const char** processArgv;

include/pharovm/pharo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,5 @@ void *readAddress(sqInt anExternalAddress);
8080

8181
EXPORT(int) isVMRunOnWorkerThread();
8282
void setMaxStacksToPrint(sqInt anInteger);
83+
84+
#define allocateMemoryBaseAddress(desiredSize, baseAddress) sqAllocateMemory(desiredSize, desiredSize, baseAddress)

smalltalksrc/Melchor/CCodeGeneratorGlobalStructure.class.st

Lines changed: 153 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,23 @@ Class {
1313
#category : #Melchor
1414
}
1515

16+
{ #category : #'CAST translation' }
17+
CCodeGeneratorGlobalStructure >> bindBlock: aTBlockNode withArgs: arguments [
18+
19+
| blockStatements argumentNames replacements |
20+
blockStatements := aTBlockNode statements.
21+
argumentNames := aTBlockNode arguments.
22+
23+
self assert: argumentNames size = arguments size.
24+
25+
replacements := argumentNames
26+
with: arguments
27+
collect: [ :name :value | name -> value ].
28+
29+
^ blockStatements collect: [ :anStatement |
30+
anStatement copy bindVariableUsesIn: replacements asDictionary ]
31+
]
32+
1633
{ #category : #'C code generator' }
1734
CCodeGeneratorGlobalStructure >> buildSortedVariablesCollection [
1835
"Build sorted vars, end result will be sorted collection based on static usage,
@@ -97,20 +114,23 @@ CCodeGeneratorGlobalStructure >> emitCVariablesOn: aStream [
97114
ifTrue: [structure]
98115
ifFalse: [nonstruct].
99116
decl := variableDeclarations at: varString ifAbsent: ['sqInt ' , varString].
100-
decl first == $# "support cgen var: #bytecodeSetSelector declareC: '#define bytecodeSetSelector 0' hack"
101-
ifTrue:
102-
[target nextPutAll: decl; cr]
103-
ifFalse:
104-
[self isGeneratingPluginCode
117+
(decl beginsWith: 'implicit') ifFalse: [
118+
decl first == $# "support cgen var: #bytecodeSetSelector declareC: '#define bytecodeSetSelector 0' hack"
105119
ifTrue:
106-
[varString = 'interpreterProxy'
107-
ifTrue: "quite special..."
108-
[self preDeclareInterpreterProxyOn: target]
109-
ifFalse: [target nextPutAll: 'static ']]
120+
[target nextPutAll: decl; cr]
110121
ifFalse:
111-
[(self vmClass mustBeGlobal: varString) ifFalse:
112-
[target nextPutAll: (inStruct ifTrue: ['_iss '] ifFalse: ['static '])]].
113-
target nextPutAll: decl; nextPut: $;; cr]].
122+
[self isGeneratingPluginCode
123+
ifTrue:
124+
[varString = 'interpreterProxy'
125+
ifTrue: "quite special..."
126+
[self preDeclareInterpreterProxyOn: target]
127+
ifFalse: [target nextPutAll: 'static ']]
128+
ifFalse:
129+
[(self vmClass mustBeGlobal: varString) ifFalse:
130+
[target nextPutAll: (inStruct ifTrue: ['_iss '] ifFalse: ['static '])]].
131+
target nextPutAll: decl; nextPut: $;; cr]
132+
]
133+
].
114134
structure
115135
nextPutAll: '#undef _iss'; cr;
116136
nextPutAll: '#if SQ_USE_GLOBAL_STRUCT'; cr;
@@ -166,13 +186,126 @@ CCodeGeneratorGlobalStructure >> emitGlobalStructFlagOn: aStream [
166186
cr
167187
]
168188

189+
{ #category : #'CAST translation' }
190+
CCodeGeneratorGlobalStructure >> generateCASTSetFieldTo: aTSendNode [
191+
192+
| structType fieldName fieldVale setFieldStatements |
193+
194+
self assert: aTSendNode arguments size = 2.
195+
196+
fieldName := aTSendNode arguments first.
197+
fieldVale := aTSendNode arguments second.
198+
199+
structType := self structTypeFor: aTSendNode receiver.
200+
201+
202+
setFieldStatements := structType asClass allSlots collect: [ :slot |
203+
| comparison |
204+
205+
comparison := TSendNode
206+
receiver: (TSendNode
207+
receiver: (TConstantNode value: slot name asString)
208+
selector: 'strcmp:'
209+
arguments: { fieldName })
210+
selector: '='
211+
arguments: { TConstantNode value: 0 }.
212+
213+
TSendNode
214+
receiver: comparison
215+
selector: 'ifTrue:'
216+
arguments: {
217+
TStatementListNode
218+
statements: {
219+
TSendNode
220+
receiver: aTSendNode receiver
221+
selector: (slot name, ':')
222+
arguments: { fieldVale }
223+
}
224+
}
225+
226+
].
227+
228+
^ CCompoundStatementNode statements: (setFieldStatements collect: [ :e | e asCASTIn: self]).
229+
230+
]
231+
232+
{ #category : #'CAST translation' }
233+
CCodeGeneratorGlobalStructure >> generateCASTWithFieldsDoSeparatedBy: aTSendNode [
234+
235+
| structType allRewrittenStatements blockSeparatorStatements fieldBlock allFieldArguments |
236+
self assert: aTSendNode arguments size = 2.
237+
self assert: aTSendNode arguments first arguments size = 2.
238+
self assert: aTSendNode arguments second arguments size = 0.
239+
240+
fieldBlock := aTSendNode arguments first.
241+
blockSeparatorStatements := aTSendNode arguments second statements.
242+
243+
structType := self structTypeFor: aTSendNode receiver.
244+
245+
allFieldArguments := structType asClass allSlots collect: [ :slot |
246+
{
247+
(TConstantNode value: slot name asString).
248+
(TSendNode
249+
receiver: aTSendNode receiver
250+
selector: slot name
251+
arguments: { }) } ].
252+
253+
allRewrittenStatements := OrderedCollection new.
254+
255+
allFieldArguments
256+
do: [ :fieldArgs |
257+
allRewrittenStatements addAll:
258+
(self bindBlock: fieldBlock withArgs: fieldArgs) ]
259+
separatedBy: [
260+
allRewrittenStatements addAll: blockSeparatorStatements ].
261+
262+
^ CCompoundStatementNode statements:
263+
(allRewrittenStatements collect: [ :e | e asCASTIn: self ])
264+
]
265+
266+
{ #category : #'CAST translation' }
267+
CCodeGeneratorGlobalStructure >> generateCASTWithStructNameDo: aTSendNode [
268+
269+
| argumentName structType rewrittenStatements aBlock |
270+
self assert: aTSendNode arguments size = 1.
271+
self assert: aTSendNode arguments first arguments size = 1.
272+
273+
structType := self structTypeFor: aTSendNode receiver.
274+
275+
aBlock := aTSendNode arguments first.
276+
argumentName := aTSendNode arguments first arguments first.
277+
278+
rewrittenStatements := self
279+
bindBlock: aBlock
280+
withArgs:
281+
{ (TConstantNode value: structType asString) }.
282+
283+
^ CCompoundStatementNode statements:
284+
(rewrittenStatements collect: [ :e | e asCASTIn: self ])
285+
]
286+
169287
{ #category : #'C code generator' }
170288
CCodeGeneratorGlobalStructure >> initialize [
171289
super initialize.
172290
localStructDef := nil. "ignored ivar - no longer used"
173291
structDefDefine := '1'
174292
]
175293

294+
{ #category : #initialization }
295+
CCodeGeneratorGlobalStructure >> initializeCASTTranslationDictionary [
296+
297+
super initializeCASTTranslationDictionary.
298+
299+
castTranslationDict at: #withStructNameDo: put: #generateCASTWithStructNameDo:.
300+
castTranslationDict at: #withFieldsDo:separatedBy: put: #generateCASTWithFieldsDoSeparatedBy:.
301+
castTranslationDict at: #setField:to: put: #generateCASTSetFieldTo:.
302+
]
303+
304+
{ #category : #public }
305+
CCodeGeneratorGlobalStructure >> isGlobalStructureBuild [
306+
^true
307+
]
308+
176309
{ #category : #utilities }
177310
CCodeGeneratorGlobalStructure >> localizeGlobalVariables [
178311
"TPR - remove all the global vars destined for the structure that are only used once - not worth the space,
@@ -215,3 +348,11 @@ CCodeGeneratorGlobalStructure >> structDefDefine: aString [
215348
'1' - which would mean always do it"
216349
structDefDefine := aString
217350
]
351+
352+
{ #category : #'CAST translation' }
353+
CCodeGeneratorGlobalStructure >> structTypeFor: structNode [
354+
355+
| nodeType |
356+
nodeType := self typeFor: structNode in: self currentMethod.
357+
^ nodeType trimRight: [ :c | { $* . $ } includes: c ]
358+
]

smalltalksrc/Melchor/VMBasicConstants.class.st

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Class {
3333
'HashMultiplyConstant',
3434
'HashMultiplyMask',
3535
'IMMUTABILITY',
36+
'PRIdSQINT',
3637
'PharoVM',
3738
'PrimErrBadArgument',
3839
'PrimErrBadIndex',
@@ -62,7 +63,8 @@ Class {
6263
'STACKVM',
6364
'SistaVM',
6465
'TempVectReadBarrier',
65-
'VMBIGENDIAN'
66+
'VMBIGENDIAN',
67+
'WIN32'
6668
],
6769
#category : #Melchor
6870
}
@@ -118,6 +120,8 @@ VMBasicConstants class >> namesDefinedAtCompileTime [
118120
WIN32 _WIN32 _WIN32_WCE
119121
WIN64 _WIN64 _WIN64_WCE
120122
123+
PRIdSQINT
124+
121125
FEATURE_FFI
122126
FEATURE_THREADED_FFI
123127
FEATURE_MESSAGE_COUNT)

0 commit comments

Comments
 (0)