[Vm-dev] VM Maker: VMMaker.oscog-eem.477.mcz
commits at source.squeak.org
commits at source.squeak.org
Fri Oct 25 20:00:56 UTC 2013
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.477.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.477
Author: eem
Time: 25 October 2013, 12:57:49.906 pm
UUID: b29f70be-1ead-4893-8f3c-f39b3d189a87
Ancestors: VMMaker.oscog-eem.476
Fix shift in headerForSlots:format:classIndex:; needs to be long long.
Make a few vitals inlined.
Fix off-by-one in printOopShortInner:.
Relax restriction in isFunctional of return type being sqInt to
being any of sqInt, usqInt, sqLong or usqLong.
C Spur VM runs up to the end of the first scavenge, when it tries
to shrink memory.
=============== Diff against VMMaker.oscog-eem.476 ===============
Item was changed:
----- Method: CogClass>>cCoerceSimple:to: (in category 'translation support') -----
cCoerceSimple: value to: cTypeString
"Type coercion for translation and simulation.
For simulation answer a suitable surrogate for the struct types"
^cTypeString caseOf:
{ [#'unsigned long'] -> [value].
[#sqInt] -> [value].
[#usqInt] -> [value].
+ [#sqLong] -> [value].
+ [#usqLong] -> [value].
[#'AbstractInstruction *'] -> [value].
[#'BytecodeFixup *'] -> [value].
[#'CogMethod *'] -> [value].
[#'char *'] -> [value].
[#'sqInt *'] -> [value].
[#'void *'] -> [value].
[#void] -> [value].
[#'void (*)()'] -> [value].
[#'void (*)(void)'] -> [value].
[#'unsigned long (*)(void)'] -> [value].
[#'void (*)(unsigned long,unsigned long)'] -> [value] }!
Item was changed:
----- Method: Spur32BitMemoryManager>>fillObj:numSlots:with: (in category 'instantiation') -----
fillObj: objOop numSlots: numSlots with: fillValue
+ <inline: true>
self assert: (objOop + self baseHeaderSize + (numSlots * self bytesPerOop) - 1)
< (self addressAfter: objOop).
objOop + self baseHeaderSize
to: objOop + self baseHeaderSize + (numSlots * self wordSize) - 1
by: self allocationUnit
do: [:p|
self longAt: p put: fillValue;
longAt: p + 4 put: fillValue]!
Item was changed:
----- Method: Spur64BitMemoryManager>>fillObj:numSlots:with: (in category 'instantiation') -----
fillObj: objOop numSlots: numSlots with: fillValue
+ <inline: true>
self assert: (objOop + self baseHeaderSize + (numSlots * self bytesPerOop) - 1)
< (self addressAfter: objOop).
objOop + self baseHeaderSize
to: objOop + self baseHeaderSize + (numSlots * self bytesPerOop) - 1
by: self allocationUnit
do: [:p| self longAt: p put: fillValue]!
Item was changed:
----- Method: SpurMemoryManager>>checkedLongAt: (in category 'memory access') -----
checkedLongAt: byteAddress
"Assumes zero-based array indexing."
<api>
+ (byteAddress asUnsignedInteger < self startOfMemory
+ or: [byteAddress asUnsignedInteger > endOfMemory
+ or: [byteAddress asUnsignedInteger > newSpaceLimit
+ and: [(segmentManager isInSegments: byteAddress asUnsignedInteger) not]]]) ifTrue:
- (self addressCouldBeObj: byteAddress) ifFalse:
[self warning: 'checkedLongAt bad address'.
coInterpreter primitiveFail].
^self longAt: byteAddress!
Item was changed:
----- Method: SpurMemoryManager>>headerForSlots:format:classIndex: (in category 'header format') -----
headerForSlots: numSlots format: formatField classIndex: classIndex
"The header format in LSB is
MSB: | 8: numSlots | (on a byte boundary)
| 2 bits | (msb,lsb = {isMarked,?})
| 22: identityHash | (on a word boundary)
| 3 bits | (msb <-> lsb = {isGrey,isPinned,isRemembered}
| 5: format | (on a byte boundary)
| 2 bits | (msb,lsb = {isImmutable,?})
| 22: classIndex | (on a word boundary) : LSB
The remaining bits (7) are used for
isImmutable (bit 23)
isRemembered (bit 29)
isPinned (bit 30)
isGrey (bit 31)
isMarked (bit 55)
leaving 2 unused bits, each next to a 22-bit field, allowing those fields to be
expanded to 23 bits.. The three bit field { isGrey, isPinned, isRemembered }
is for bits that are never set in young objects. This allows the remembered
table to be pruned when full by using these bits as a reference count of
newSpace objects from the remembered table. Objects with a high count
should be tenured to prune the remembered table."
<returnTypeC: #usqLong>
+ <inline: true>
+ ^ ((self cCoerceSimple: numSlots to: #usqLong) << self numSlotsFullShift)
- ^ (numSlots << self numSlotsFullShift)
+ (formatField << self formatShift)
+ classIndex!
Item was changed:
----- Method: SpurMemoryManager>>unlinkSolitaryFreeTreeNode: (in category 'free space') -----
unlinkSolitaryFreeTreeNode: freeTreeNode
"Unlink a freeTreeNode. Assumes the node has no list (null next link)."
| parent smaller larger |
self assert: (self fetchPointer: self freeChunkNextIndex ofObject: freeTreeNode) = 0.
"case 1. interior node has one child, P = parent, N = node, S = subtree (mirrored for large vs small)
___ ___
| P | | P |
_/_ _/_
| N | => | S |
_/_
| S |
case 2: interior node has two children, , P = parent, N = node, L = smaller, left subtree, R = larger, right subtree.
add the left subtree to the bottom left of the right subtree (mirrored for large vs small)
___ ___
| P | | P |
_/_ _/_
| N | => | R |
_/_ _\_ _/_
| L | | R | | L |"
smaller := self fetchPointer: self freeChunkSmallerIndex ofFreeChunk: freeTreeNode.
larger := self fetchPointer: self freeChunkLargerIndex ofFreeChunk: freeTreeNode.
parent := self fetchPointer: self freeChunkParentIndex ofFreeChunk: freeTreeNode.
parent = 0
ifTrue: "no parent; stitch the subnodes back into the root"
[smaller = 0
ifTrue:
[self storePointer: self freeChunkParentIndex ofFreeChunk: larger withValue: 0.
freeLists at: 0 put: larger]
ifFalse:
[self storePointer: self freeChunkParentIndex ofFreeChunk: smaller withValue: 0.
freeLists at: 0 put: smaller.
larger ~= 0 ifTrue:
[self addFreeSubTree: larger]]]
ifFalse: "parent; stitch back into appropriate side of parent."
[smaller = 0
ifTrue: [self storePointer: (freeTreeNode = (self fetchPointer: self freeChunkSmallerIndex ofFreeChunk: parent)
ifTrue: [self freeChunkSmallerIndex]
ifFalse: [self freeChunkLargerIndex])
ofFreeChunk: parent
withValue: larger.
+ larger ~= 0 ifTrue:
+ [self storePointer: self freeChunkParentIndex
+ ofObject: larger
+ withValue: parent]]
- self storePointer: self freeChunkParentIndex
- ofObject: larger
- withValue: parent]
ifFalse:
[self storePointer: (freeTreeNode = (self fetchPointer: self freeChunkSmallerIndex ofFreeChunk: parent)
ifTrue: [self freeChunkSmallerIndex]
ifFalse: [self freeChunkLargerIndex])
ofFreeChunk: parent
withValue: smaller.
self storePointer: self freeChunkParentIndex
ofObject: smaller
withValue: parent.
larger ~= 0 ifTrue:
[self addFreeSubTree: larger]]]!
Item was changed:
----- Method: SpurSegmentManager>>isInSegments: (in category 'testing') -----
isInSegments: address
+ <var: #address type: #usqInt>
0 to: numSegments - 1 do:
[:i|
address < (segments at: i) segStart ifTrue:
[^false].
address < ((segments at: i) segStart + (segments at: i) segSize) ifTrue:
[^true]].
^false!
Item was changed:
----- Method: StackInterpreter>>nameOfClass: (in category 'debug printing') -----
nameOfClass: classOop
"Brain-damaged nameOfClass: for C VM. Does *not* answer Foo class for metaclasses.
Use e.g. classIsMeta: to avoid being fooled."
<inline: false>
<returnTypeC: 'char *'>
| numSlots |
numSlots := objectMemory numSlotsOf: classOop.
numSlots = metaclassNumSlots ifTrue:
[^self nameOfClass: (objectMemory fetchPointer: thisClassIndex ofObject: classOop)].
numSlots <= classNameIndex ifTrue:
[^'bad class'].
+ ^objectMemory firstIndexableField: (objectMemory fetchPointer: classNameIndex ofObject: classOop)!
- ^objectMemory firstFixedField: (objectMemory fetchPointer: classNameIndex ofObject: classOop)!
Item was changed:
----- Method: StackInterpreter>>printOopShortInner: (in category 'debug printing') -----
printOopShortInner: oop
| classOop name nameLen |
<var: #name type: #'char *'>
<inline: true>
(objectMemory isImmediate: oop) ifTrue:
[(objectMemory isImmediateCharacter: oop) ifTrue:
[self printChar: $$;
printChar: (objectMemory characterValueOf: oop);
printChar: $(;
printHex: (objectMemory integerValueOf: oop);
printChar: $).
^nil].
self printNum: (objectMemory integerValueOf: oop);
printChar: $(;
printHex: (objectMemory integerValueOf: oop);
printChar: $).
^nil].
(objectMemory addressCouldBeObj: oop) ifFalse:
[self print: ((oop bitAnd: objectMemory allocationUnit - 1) ~= 0
ifTrue: [' is misaligned']
ifFalse: [' is not on the heap']); cr.
^nil].
(self isFloatObject: oop) ifTrue:
[self printFloat: (self dbgFloatValueOf: oop).
^nil].
classOop := objectMemory fetchClassOfNonImm: oop.
(objectMemory addressCouldBeObj: classOop) ifFalse:
[self print: 'a ??'. ^nil].
(objectMemory numSlotsOf: classOop) = metaclassNumSlots ifTrue:
[self printNameOfClass: oop count: 5.
^nil].
oop = objectMemory nilObject ifTrue: [self print: 'nil'. ^nil].
oop = objectMemory trueObject ifTrue: [self print: 'true'. ^nil].
oop = objectMemory falseObject ifTrue: [self print: 'false'. ^nil].
nameLen := self lengthOfNameOfClass: classOop.
nameLen = 0 ifTrue: [self print: 'a ??'. ^nil].
name := self nameOfClass: classOop.
nameLen = 10 ifTrue:
[(self str: name n: 'ByteString' cmp: 10) not "strncmp is weird" ifTrue:
[self printChar: $'; printStringOf: oop; printChar: $'.
^nil].
(self str: name n: 'ByteSymbol' cmp: 10) not "strncmp is weird" ifTrue:
[self printChar: $#; printStringOf: oop.
^nil]].
(nameLen = 9 and: [(self str: name n: 'Character' cmp: 9) not]) ifTrue:
[self printChar: $$; printChar: (objectMemory integerValueOf: (objectMemory fetchPointer: 0 ofObject: oop)).
^nil].
self print: 'a(n) '.
+ 0 to: nameLen - 1 do: [:i| self printChar: (name at: i)].
- 1 to: nameLen do: [:i| self printChar: (name at: i)].
"Try to spot association-like things; they're all subclasses of LookupKey"
((objectMemory instanceSizeOf: classOop) = (ValueIndex + 1)
and: [(self superclassOf: classOop) = (self superclassOf: (objectMemory fetchClassOfNonImm: (objectMemory splObj: SchedulerAssociation)))
and: [objectMemory isBytes: (objectMemory fetchPointer: KeyIndex ofObject: oop)]]) ifTrue:
[self space;
printOopShort: (objectMemory fetchPointer: KeyIndex ofObject: oop);
print: ' -> ';
printHex: (objectMemory fetchPointer: ValueIndex ofObject: oop)]!
Item was changed:
----- Method: TMethod>>isFunctional (in category 'inlining') -----
isFunctional
"Answer true if the receiver is a functional method. That is, if it
consists of a single return statement of an expression that contains
no other returns.
+ Answer false for methods with return types other than the simple
+ integer types to work around bugs in the inliner."
- Answer false for methods with return types other than #sqInt to work
- around bugs in the inliner."
(parseTree statements size = 1 and:
[parseTree statements last isReturn]) ifFalse: [ ^false ].
parseTree statements last expression nodesDo: [ :n | n isReturn ifTrue: [ ^false ]].
+ ^#(sqInt usqInt sqLong usqLong) includes: returnType!
- returnType = #sqInt ifFalse:[^false].
- ^true!
Item was changed:
----- Method: TMethod>>maybeBreakFor:in: (in category 'inlining') -----
maybeBreakFor: aNode in: aCodeGen
"convenient for debugging..."
(aNode isSend
and: [(aCodeGen breakSrcInlineSelector notNil or: [aCodeGen breakDestInlineSelector notNil])
and: [(aCodeGen breakSrcInlineSelector ifNil: [true] ifNotNil: [:srcSel| srcSel = aNode selector])
and: [aCodeGen breakDestInlineSelector ifNil: [true] ifNotNil: [:dstSel| dstSel = selector]]]]) ifTrue:
+ [self halt: selector]!
- [self halt]!
More information about the Vm-dev
mailing list