Skip to content

Commit e71192e

Browse files
authored
Merge pull request #844 from tesonep/adding-option-for-pin-behaviour
Adding option for pin behaviour
2 parents 0459357 + d1180d7 commit e71192e

File tree

6 files changed

+89
-18
lines changed

6 files changed

+89
-18
lines changed

include/pharovm/parameters/parameters.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ typedef struct VMParameters_
130130
// FIXME: Passing this environment vector seems hackish. getenv should be used instead.
131131
const char** environmentVector;
132132

133+
// When pinning young objects, the objects are clonned into the old space.
134+
// Trying to allocate it in a segment with already pinned objects
135+
// Does the clonning process avoid this search and allocate the clonned object anywhere?
136+
// DEFAULT: false
137+
bool avoidSearchingSegmentsWithPinnedObjects;
138+
133139
VMParameterVector vmParameters;
134140
VMParameterVector imageParameters;
135141
} VMParameters;

smalltalksrc/VMMaker/SpurMemoryManager.class.st

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,8 @@ Class {
618618
'permSpaceFreeStart',
619619
'fromOldSpaceRememberedSet',
620620
'fromPermToOldSpaceRememberedSet',
621-
'fromPermToNewSpaceRememberedSet'
621+
'fromPermToNewSpaceRememberedSet',
622+
'avoidSearchingSegmentsWithPinnedObjects'
622623
],
623624
#classVars : [
624625
'BitsPerByte',
@@ -2403,14 +2404,20 @@ SpurMemoryManager >> allocateSlots: numSlots format: formatField classIndex: cla
24032404

24042405
{ #category : 'allocation' }
24052406
SpurMemoryManager >> allocateSlotsForPinningInOldSpace: numSlots bytes: totalBytes format: formatField classIndex: classIndex [
2406-
"Answer the oop of a chunk of space in oldSpace with numSlots slots. Try and
2407-
allocate in a segment that already includes pinned objects. The header of the
2408-
result will have been filled-in but not the contents."
2407+
"Answer the oop of a chunk of space in oldSpace with numSlots slots.
2408+
Try and allocate in a segment that already includes pinned objects.
2409+
If the option #avoidSearchingSegmentsWithPinnedObjects is true, we don't do the search.
2410+
For some users this can have a good impact when having many pinned objects used in FFI calls.
2411+
The header of the result will have been filled-in but not the contents."
24092412
<var: #totalBytes type: #usqInt>
24102413
<inline: false>
24112414
| chunk newOop |
2412-
chunk := self allocateOldSpaceChunkOfBytes: totalBytes
2413-
suchThat: [:f| (segmentManager segmentContainingObj: f) containsPinned].
2415+
2416+
chunk := avoidSearchingSegmentsWithPinnedObjects
2417+
ifTrue: [ nil ]
2418+
ifFalse: [self allocateOldSpaceChunkOfBytes: totalBytes
2419+
suchThat: [:f| (segmentManager segmentContainingObj: f) containsPinned]].
2420+
24142421
chunk ifNil:
24152422
[chunk := self allocateOldSpaceChunkOfBytes: totalBytes.
24162423
chunk ifNil: [^nil].
@@ -5947,6 +5954,14 @@ SpurMemoryManager >> gcStartUsecs [
59475954
^gcStartUsecs
59485955
]
59495956

5957+
{ #category : 'accessing' }
5958+
SpurMemoryManager >> getAvoidSearchingSegmentsWithPinnedObjects [
5959+
5960+
<api>
5961+
5962+
^ avoidSearchingSegmentsWithPinnedObjects
5963+
]
5964+
59505965
{ #category : 'accessing' }
59515966
SpurMemoryManager >> getFromOldSpaceRememberedSet [
59525967

@@ -6637,6 +6652,8 @@ SpurMemoryManager >> initialize [
66376652
maxOldSpaceSize := self class initializationOptions
66386653
ifNotNil: [:initOpts| initOpts at: #maxOldSpaceSize ifAbsent: [0]]
66396654
ifNil: [0].
6655+
6656+
avoidSearchingSegmentsWithPinnedObjects := false.
66406657

66416658
]
66426659

@@ -11692,6 +11709,15 @@ SpurMemoryManager >> set: objOop classIndexTo: classIndex formatTo: format [
1169211709
self subclassResponsibility
1169311710
]
1169411711

11712+
{ #category : 'accessing' }
11713+
SpurMemoryManager >> setAvoidSearchingSegmentsWithPinnedObjects: aValue [
11714+
11715+
<api>
11716+
<var: #aValue type: #sqInt>
11717+
11718+
avoidSearchingSegmentsWithPinnedObjects := aValue
11719+
]
11720+
1169511721
{ #category : 'spur bootstrap' }
1169611722
SpurMemoryManager >> setCheckForLeaks: integerFlags [
1169711723
" 0 = do nothing.

smalltalksrc/VMMaker/StackInterpreterPrimitives.class.st

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,7 +1697,8 @@ StackInterpreterPrimitives >> primitiveGetVMParameter: index [
16971697
[84] -> [^objectMemory integerObjectOf:
16981698
objectMemory getFromPermToNewSpaceRememberedSet rememberedSetSize].
16991699
[85] -> [^objectMemory integerObjectOf:
1700-
objectMemory getFromPermToNewSpaceRememberedSet rememberedSetLimit]}
1700+
objectMemory getFromPermToNewSpaceRememberedSet rememberedSetLimit].
1701+
[86] -> [^ objectMemory getAvoidSearchingSegmentsWithPinnedObjects ifTrue: [ objectMemory trueObject ] ifFalse: [objectMemory falseObject]]}
17011702
otherwise: [^nil]
17021703
]
17031704

@@ -2707,15 +2708,26 @@ StackInterpreterPrimitives >> primitiveSetVMParameter: index arg: argOop [
27072708
| arg result |
27082709

27092710
"argOop read & checks; in most cases this is an integer parameter. In some it is either an integer or a Float"
2710-
(index = 17 or: [index = 55 or: [index = 68]])
2711-
ifTrue:
2712-
[((objectMemory isFloatInstance: argOop)
2711+
index
2712+
caseOf: {
2713+
[17] -> [((objectMemory isFloatInstance: argOop)
27132714
or: [objectMemory isIntegerObject: argOop]) ifFalse:
2714-
[^self primitiveFailFor: PrimErrBadArgument]]
2715-
ifFalse:
2716-
[(objectMemory isIntegerObject: argOop) ifFalse:
2715+
[^self primitiveFailFor: PrimErrBadArgument]].
2716+
[55] -> [((objectMemory isFloatInstance: argOop)
2717+
or: [objectMemory isIntegerObject: argOop]) ifFalse:
2718+
[^self primitiveFailFor: PrimErrBadArgument]].
2719+
[68] -> [((objectMemory isFloatInstance: argOop)
2720+
or: [objectMemory isIntegerObject: argOop]) ifFalse:
2721+
[^self primitiveFailFor: PrimErrBadArgument]].
2722+
[86] -> [
2723+
(objectMemory isBooleanObject: argOop) ifFalse:
2724+
[^self primitiveFailFor: PrimErrBadArgument].
2725+
arg := objectMemory booleanValueOf: argOop
2726+
]}
2727+
otherwise: [
2728+
(objectMemory isIntegerObject: argOop) ifFalse:
27172729
[^self primitiveFailFor: PrimErrBadArgument].
2718-
arg := objectMemory integerValueOf: argOop].
2730+
arg := objectMemory integerValueOf: argOop ].
27192731

27202732
"assume failure, then set success for handled indices"
27212733
self primitiveFailFor: PrimErrBadArgument.
@@ -2792,7 +2804,14 @@ StackInterpreterPrimitives >> primitiveSetVMParameter: index arg: argOop [
27922804
[79] -> [ (arg between: 0 and: 65535) ifTrue:
27932805
[result := objectMemory integerObjectOf: self getImageVersion.
27942806
self setImageVersion: arg.
2795-
self initPrimCall] ] }
2807+
self initPrimCall] ].
2808+
[86] -> [
2809+
result := objectMemory getAvoidSearchingSegmentsWithPinnedObjects
2810+
ifTrue: [objectMemory trueObject]
2811+
ifFalse: [objectMemory falseObject].
2812+
2813+
objectMemory setAvoidSearchingSegmentsWithPinnedObjects: arg.
2814+
self initPrimCall ]}
27962815
otherwise: [].
27972816

27982817
self successful
@@ -3984,7 +4003,7 @@ StackInterpreterPrimitives >> primitiveVMParameter [
39844003
Otherwise the *real* list is in the code: `StackInterpreterPrimitives>>#primitiveGetVMParameter:`"
39854004

39864005
| paramsArraySize index |
3987-
paramsArraySize := 85.
4006+
paramsArraySize := 86.
39884007
argumentCount = 0 ifTrue: [^self primitiveAllVMParameters: paramsArraySize].
39894008
argumentCount > 2 ifTrue: [^self primitiveFailFor: PrimErrBadNumArgs].
39904009

smalltalksrc/VMMakerTests/VMPrimitiveTest.class.st

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5459,10 +5459,10 @@ VMPrimitiveTest >> testPrimitiveVMParameterReturnsArrayOfOops [
54595459
interpreter preemptionYields: true.
54605460
interpreter primitiveVMParameter.
54615461

5462-
"Check this is an array that has 85 OOP entries"
5462+
"Check this is an array that has 86 OOP entries"
54635463
self assert: (memory isArray: interpreter stackTop).
54645464
slots := memory numSlotsOf: interpreter stackTop.
5465-
self assert: slots equals: 85.
5465+
self assert: slots equals: 86.
54665466

54675467
0 to: slots - 1 do: [ :i |
54685468
memory okayOop: (memory fetchPointer: i ofObject: interpreter stackTop) ]

src/client.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern sqInt setMaxOldSpaceSize(usqInt limit);
99
extern void setDesiredCogCodeSize(sqInt anInteger);
1010
extern sqInt setDesiredEdenBytes(usqLong bytes);
1111
extern void setMinimalPermSpaceSize(sqInt min);
12+
extern void setAvoidSearchingSegmentsWithPinnedObjects(sqInt aValue);
1213

1314
#if defined(__GNUC__) && ( defined(i386) || defined(__i386) || defined(__i386__) \
1415
|| defined(i486) || defined(__i486) || defined (__i486__) \
@@ -70,6 +71,8 @@ EXPORT(int) vm_init(VMParameters* parameters)
7071
setDesiredEdenBytes(parameters->edenSize);
7172
setMinimalPermSpaceSize(parameters->minPermSpaceSize);
7273

74+
setAvoidSearchingSegmentsWithPinnedObjects(parameters->avoidSearchingSegmentsWithPinnedObjects);
75+
7376
if(parameters->maxCodeSize > 0) {
7477
#ifndef COGVM
7578
logError("StackVM does not accept maxCodeSize");

src/parameters/parameters.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ static VMErrorCode processMaxCodeSpaceSizeOption(const char *argument, VMParamet
7676
static VMErrorCode processEdenSizeOption(const char *argument, VMParameters * params);
7777
static VMErrorCode processWorkerOption(const char *argument, VMParameters * params);
7878
static VMErrorCode processMinPermSpaceSizeOption(const char *argument, VMParameters * params);
79+
static VMErrorCode processAvoidSearchingSegmentsWithPinnedObjects(const char *argument, VMParameters * params);
7980

8081
static const VMParameterSpec vm_parameters_spec[] =
8182
{
@@ -94,6 +95,8 @@ static const VMParameterSpec vm_parameters_spec[] =
9495
{.name = "codeSize", .hasArgument = true, .function = processMaxCodeSpaceSizeOption},
9596
{.name = "edenSize", .hasArgument = true, .function = processEdenSizeOption},
9697
{.name = "minPermSpaceSize", .hasArgument = true, .function = processMinPermSpaceSizeOption},
98+
99+
{.name = "avoidSearchingSegmentsWithPinnedObjects", .hasArgument = false, .function = processAvoidSearchingSegmentsWithPinnedObjects},
97100
#ifdef __APPLE__
98101
// This parameter is passed by the XCode debugger.
99102
{.name = "NSDocumentRevisionsDebugMode", .hasArgument = false, .function = NULL},
@@ -437,6 +440,12 @@ vm_printUsageTo(FILE *out)
437440
" --minPermSpaceSize=<size>[mk] Sets the size of eden\n"
438441
" It is possible to use k(kB), M(MB) and G(GB).\n"
439442
"\n"
443+
" --avoidSearchingSegmentsWithPinnedObjects\n"
444+
" When pinning young objects, the objects are clonned into the old space.\n"
445+
" It tries to allocate the object in a segment with already pinned objects.\n"
446+
" Avoid the clonning process avoid this search and allocate the clonned object anywhere?\n"
447+
"\n"
448+
"\n"
440449
"Notes:\n"
441450
"\n"
442451
" <imageName> defaults to `Pharo.image'.\n"
@@ -573,6 +582,13 @@ processPrintVersionOption(const char* argument, VMParameters * params)
573582
return VM_ERROR_EXIT_WITH_SUCCESS;
574583
}
575584

585+
static VMErrorCode
586+
processAvoidSearchingSegmentsWithPinnedObjects(const char* argument, VMParameters * params)
587+
{
588+
params->avoidSearchingSegmentsWithPinnedObjects = true;
589+
return VM_SUCCESS;
590+
}
591+
576592
static VMErrorCode
577593
processVMOptions(VMParameters* parameters)
578594
{
@@ -723,6 +739,7 @@ vm_parameters_init(VMParameters *parameters){
723739
parameters->isDefaultImage = false;
724740
parameters->defaultImageFound = false;
725741
parameters->isInteractiveSession = false;
742+
parameters->avoidSearchingSegmentsWithPinnedObjects = false;
726743

727744
parameters->isWorker = false;
728745

0 commit comments

Comments
 (0)