[Vm-dev] VM Maker: VMMaker.oscog-nice.1979.mcz
commits at source.squeak.org
commits at source.squeak.org
Fri Nov 4 21:00:10 UTC 2016
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1979.mcz
==================== Summary ====================
Name: VMMaker.oscog-nice.1979
Author: nice
Time: 4 November 2016, 9:58:00.806651 pm
UUID: 2abf6236-cd7c-42c2-bf82-515ac9ada054
Ancestors: VMMaker.oscog-nice.1978
Introduce sqIntptr_t and usqIntptr_t in VMMaker (image side) for LLP64 compatibility - but do not yet use them.
These are integers long enough to hold a target machine pointer (BytesPerWord).
These should later replace most usage of #long and #'unsigned long'.
They are already defined in sqMemoryAccess.h.
Add enough machinery for generating and simulating these types, inferring size, converting signedness etc....
Introduce asUnsignedIntegerPtr which will convert to (cast to) a usqIntptr_t.
same for asIntegerPtr -> sqIntptr_t.
They should replace most usage of asUnsignedLong and asLong in the future.
Unless we don't want a machine word, but an oop, in which case we should use asUnsignedInteger (-> usqInt) or asInteger (-> sqInt) (typically to turn a longAt: into an unsignedLongAt: - because longAt: answers a sqInt not a long!)
Restore the size of sqInt/usqInt as BytePerOop.
BytesPerOop matches BytesPerWord for Spur currently, but the CCodeGenerator should be Spur-agnostic if possible.
Move sqInt/usqInt check ahead in simulated sizeof: because most variables are of this type.
=============== Diff against VMMaker.oscog-eem.1977 ===============
Item was added:
+ ----- Method: CCodeGenerator>>generateAsIntegerPtr:on:indent: (in category 'C translation') -----
+ generateAsIntegerPtr: msgNode on: aStream indent: level
+ "Generate the C code for this message onto the given stream."
+
+ aStream nextPutAll:'((sqIntptr_t)'.
+ self emitCExpression: msgNode receiver on: aStream.
+ aStream nextPut: $)!
Item was added:
+ ----- Method: CCodeGenerator>>generateAsUnsignedIntegerPtr:on:indent: (in category 'C translation') -----
+ generateAsUnsignedIntegerPtr: msgNode on: aStream indent: level
+ "Generate the C code for this message onto the given stream."
+
+ aStream nextPutAll:'((usqIntptr_t)'.
+ self emitCExpression: msgNode receiver on: aStream.
+ aStream nextPut: $)!
Item was changed:
----- Method: CCodeGenerator>>initializeCTranslationDictionary (in category 'C translation support') -----
initializeCTranslationDictionary
"Initialize the dictionary mapping message names to actions for C code generation."
| pairs |
translationDict := Dictionary new: 200.
pairs := #(
#& #generateAnd:on:indent:
#| #generateOr:on:indent:
#abs #generateAbs:on:indent:
#and: #generateSequentialAnd:on:indent:
#or: #generateSequentialOr:on:indent:
#not #generateNot:on:indent:
#+ #generatePlus:on:indent:
#- #generateMinus:on:indent:
#negated #generateNegated:on:indent:
#* #generateTimes:on:indent:
#/ #generateDivide:on:indent:
#// #generateDivide:on:indent:
#\\ #generateModulo:on:indent:
#<< #generateShiftLeft:on:indent:
#>> #generateShiftRight:on:indent:
#>>> #generateSignedShiftRight:on:indent:
#min: #generateMin:on:indent:
#max: #generateMax:on:indent:
#between:and: #generateBetweenAnd:on:indent:
#bitAnd: #generateBitAnd:on:indent:
#bitOr: #generateBitOr:on:indent:
#bitXor: #generateBitXor:on:indent:
#bitShift: #generateBitShift:on:indent:
#signedBitShift: #generateSignedBitShift:on:indent:
#bitInvert32 #generateBitInvert:on:indent:
#bitInvert64 #generateBitInvert:on:indent:
#bitClear: #generateBitClear:on:indent:
#truncateTo: #generateTruncateTo:on:indent:
#rounded #generateRounded:on:indent:
#byteSwap32 #generateByteSwap32:on:indent:
#byteSwap64 #generateByteSwap64:on:indent:
#byteSwapped32IfBigEndian: generateByteSwap32IfBigEndian:on:indent:
#byteSwapped64IfBigEndian: generateByteSwap64IfBigEndian:on:indent:
#< #generateLessThan:on:indent:
#<= #generateLessThanOrEqual:on:indent:
#= #generateEqual:on:indent:
#> #generateGreaterThan:on:indent:
#>= #generateGreaterThanOrEqual:on:indent:
#~= #generateNotEqual:on:indent:
#== #generateEqual:on:indent:
#~~ #generateNotEqual:on:indent:
#isNil #generateIsNil:on:indent:
#notNil #generateNotNil:on:indent:
#whileTrue: #generateWhileTrue:on:indent:
#whileFalse: #generateWhileFalse:on:indent:
#whileTrue #generateDoWhileTrue:on:indent:
#whileFalse #generateDoWhileFalse:on:indent:
#to:do: #generateToDo:on:indent:
#to:by:do: #generateToByDo:on:indent:
#repeat #generateRepeat:on:indent:
#timesRepeat: #generateTimesRepeat:on:indent:
#ifTrue: #generateIfTrue:on:indent:
#ifFalse: #generateIfFalse:on:indent:
#ifTrue:ifFalse: #generateIfTrueIfFalse:on:indent:
#ifFalse:ifTrue: #generateIfFalseIfTrue:on:indent:
#ifNotNil: #generateIfNotNil:on:indent:
#ifNil: #generateIfNil:on:indent:
#ifNotNil:ifNil: #generateIfNotNilIfNil:on:indent:
#ifNil:ifNotNil: #generateIfNilIfNotNil:on:indent:
#at: #generateAt:on:indent:
#at:put: #generateAtPut:on:indent:
#basicAt: #generateAt:on:indent:
#basicAt:put: #generateAtPut:on:indent:
#integerValueOf: #generateIntegerValueOf:on:indent:
#integerObjectOf: #generateIntegerObjectOf:on:indent:
#isIntegerObject: #generateIsIntegerObject:on:indent:
#cCode: #generateInlineCCode:on:indent:
#cCode:inSmalltalk: #generateInlineCCode:on:indent:
#cPreprocessorDirective: #generateInlineCPreprocessorDirective:on:indent:
#cppIf:ifTrue:ifFalse: #generateInlineCppIfElse:on:indent:
#cppIf:ifTrue: #generateInlineCppIfElse:on:indent:
#cCoerce:to: #generateCCoercion:on:indent:
#cCoerceSimple:to: #generateCCoercion:on:indent:
#addressOf: #generateAddressOf:on:indent:
#addressOf:put: #generateAddressOf:on:indent:
#asAddress:put: #generateAsAddress:on:indent:
#signedIntFromLong64 #generateSignedIntFromLong64:on:indent:
#signedIntFromLong #generateSignedIntFromLong:on:indent:
#signedIntFromShort #generateSignedIntFromShort:on:indent:
#signedIntToLong64 #generateSignedIntToLong64:on:indent:
#signedIntToLong #generateSignedIntToLong:on:indent:
#signedIntToShort #generateSignedIntToShort:on:indent:
#preIncrement #generatePreIncrement:on:indent:
#preDecrement #generatePreDecrement:on:indent:
#inline: #generateInlineDirective:on:indent:
#asFloat #generateAsFloat:on:indent:
#asInteger #generateAsInteger:on:indent:
+ #asIntegerPtr #generateAsIntegerPtr:on:indent:
#asUnsignedInteger #generateAsUnsignedInteger:on:indent:
+ #asUnsignedIntegerPtr #generateAsUnsignedIntegerPtr:on:indent:
#asLong #generateAsLong:on:indent:
#asUnsignedLong #generateAsUnsignedLong:on:indent:
#asUnsignedLongLong #generateAsUnsignedLongLong:on:indent:
#asVoidPointer #generateAsVoidPointer:on:indent:
#asSymbol #generateAsSymbol:on:indent:
#flag: #generateFlag:on:indent:
#anyMask: #generateBitAnd:on:indent:
#allMask: #generateAllMask:on:indent:
#noMask: #generateNoMask:on:indent:
#raisedTo: #generateRaisedTo:on:indent:
#touch: #generateTouch:on:indent:
#bytesPerOop #generateBytesPerOop:on:indent:
#bytesPerWord #generateBytesPerWord:on:indent:
#wordSize #generateBytesPerWord:on:indent:
#baseHeaderSize #generateBaseHeaderSize:on:indent:
#minSmallInteger #generateSmallIntegerConstant:on:indent:
#maxSmallInteger #generateSmallIntegerConstant:on:indent:
#sharedCodeNamed:inCase: #generateSharedCodeDirective:on:indent:
#perform: #generatePerform:on:indent:
#perform:with: #generatePerform:on:indent:
#perform:with:with: #generatePerform:on:indent:
#perform:with:with:with: #generatePerform:on:indent:
#perform:with:with:with:with: #generatePerform:on:indent:
#perform:with:with:with:with:with: #generatePerform:on:indent:
#value #generateValue:on:indent:
#value: #generateValue:on:indent:
#value:value: #generateValue:on:indent:
#value:value:value: #generateValue:on:indent:
#value:value:value:value: #generateValue:on:indent:
#deny: #generateDeny:on:indent:
#shouldNotImplement #generateSmalltalkMetaError:on:indent:
#shouldBeImplemented #generateSmalltalkMetaError:on:indent:
#subclassResponsibility #generateSmalltalkMetaError:on:indent:
).
1 to: pairs size by: 2 do: [:i |
translationDict at: (pairs at: i) put: (pairs at: i + 1)].
pairs := #(
#ifTrue: #generateIfTrueAsArgument:on:indent:
#ifFalse: #generateIfFalseAsArgument:on:indent:
#ifTrue:ifFalse: #generateIfTrueIfFalseAsArgument:on:indent:
#ifFalse:ifTrue: #generateIfFalseIfTrueAsArgument:on:indent:
#ifNotNil: #generateIfNotNilAsArgument:on:indent:
#ifNil: #generateIfNilAsArgument:on:indent:
#ifNotNil:ifNil: #generateIfNotNilIfNilAsArgument:on:indent:
#ifNil:ifNotNil: #generateIfNilIfNotNilAsArgument:on:indent:
#cCode: #generateInlineCCodeAsArgument:on:indent:
#cCode:inSmalltalk: #generateInlineCCodeAsArgument:on:indent:
#cppIf:ifTrue:ifFalse: #generateInlineCppIfElseAsArgument:on:indent:
#cppIf:ifTrue: #generateInlineCppIfElseAsArgument:on:indent:
#value #generateValueAsArgument:on:indent:
#value: #generateValueAsArgument:on:indent:
#value:value: #generateValueAsArgument:on:indent:
).
asArgumentTranslationDict := Dictionary new: 8.
1 to: pairs size by: 2 do: [:i |
asArgumentTranslationDict at: (pairs at: i) put: (pairs at: i + 1)].
!
Item was changed:
----- Method: CCodeGenerator>>isIntegralCType: (in category 'inlining') -----
isIntegralCType: aCType "<String>"
+ ^(#('sqLong' 'usqLong' 'sqInt' 'usqInt' 'sqIntptr_t' 'usqIntptr_t'
- ^(#('sqLong' 'usqLong' 'sqInt' 'usqInt'
'long' 'int' 'short' 'char' 'signed char'
'size_t' 'pid_t') includes: aCType asString)
or: [(aCType beginsWith: 'unsigned') "Accept e.g. 'unsigned long' and also 'unsigned : 8'"
and: [(aCType includesAnyOf: '[*]') not]]!
Item was changed:
----- Method: CCodeGenerator>>returnTypeForSend:in:ifNil: (in category 'type inference') -----
returnTypeForSend: sendNode in: aTMethod ifNil: typeIfNil
"Answer the return type for a send. Unbound sends default to typeIfNil.
Methods with types as yet unknown have a type determined either by the
kernelReturnTypes or the table below, or, if they are in neither set, then nil.
The inferred type should match as closely as possible the C type of
generated expessions so that inlining would not change the expression.
If there is a method for sel but its return type is as yet unknown it mustn't
be defaulted, since on a subsequent pass its type may be computable."
| sel methodOrNil |
methodOrNil := self anyMethodNamed: (sel := sendNode selector).
(methodOrNil notNil and: [methodOrNil returnType notNil]) ifTrue:
[^self baseTypeForType: methodOrNil returnType].
^kernelReturnTypes
at: sel
ifAbsent:
[sel
caseOf: {
[#integerValueOf:] -> [#sqInt].
[#isIntegerObject:] -> [#int].
[#negated] -> [self promoteArithmeticTypes: (self typeFor: sendNode receiver in: aTMethod) and: #int].
[#+] -> [self typeForArithmetic: sendNode in: aTMethod].
[#-] -> [self typeForArithmetic: sendNode in: aTMethod].
[#*] -> [self typeForArithmetic: sendNode in: aTMethod].
[#/] -> [self typeForArithmetic: sendNode in: aTMethod].
[#//] -> [self typeForArithmetic: sendNode in: aTMethod].
[#\\] -> [self typeForArithmetic: sendNode in: aTMethod].
[#rem:] -> [self typeForArithmetic: sendNode in: aTMethod].
[#quo:] -> [self typeForArithmetic: sendNode in: aTMethod].
"C99 Sec Bitwise shift operators ... 3 Sematics ...
The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand..."
[#>>] -> [self typeFor: sendNode receiver in: aTMethod].
[#<<] -> [self typeFor: sendNode receiver in: aTMethod].
[#addressOf:] -> [(self typeFor: sendNode receiver in: aTMethod)
ifNil: [#sqInt]
ifNotNil: [:type| type, (type last isLetter ifTrue: [' *'] ifFalse: ['*'])]].
[#at:] -> [self typeForDereference: sendNode in: aTMethod].
[#bitAnd:] -> [self typeForArithmetic: sendNode in: aTMethod].
[#bitOr:] -> [self typeForArithmetic: sendNode in: aTMethod].
[#bitXor:] -> [self typeForArithmetic: sendNode in: aTMethod].
[#bitClear:] -> [self typeForArithmetic: sendNode in: aTMethod].
[#bitInvert32] -> [#'unsigned int'].
[#bitInvert64] -> [self promoteArithmeticTypes: (self typeFor: sendNode receiver in: aTMethod) and: #int].
[#byteSwap32] -> [#'unsigned int'].
[#byteSwap64] -> [#'unsigned long long'].
[#byteSwapped32IfBigEndian:] -> [#'unsigned int'].
[#byteSwapped64IfBigEndian:] -> [#'unsigned long long'].
[#=] -> [#int].
[#~=] -> [#int].
[#==] -> [#int].
[#~~] -> [#int].
[#<] -> [#int].
[#<=] -> [#int].
[#>] -> [#int].
[#>=] -> [#int].
[#between:and:] -> [#int].
[#anyMask:] -> [#int].
[#allMask:] -> [#int].
[#noMask:] -> [#int].
[#isNil] -> [#int].
[#notNil] -> [#int].
[#&] -> [#int].
[#|] -> [#int].
[#not] -> [#int].
[#asFloat] -> [#double].
[#atan] -> [#double].
[#exp] -> [#double].
[#log] -> [#double].
[#sin] -> [#double].
[#sqrt] -> [#double].
[#asLong] -> [#long].
[#asInteger] -> [#sqInt].
+ [#asIntegerPtr] -> [#'sqIntptr_t'].
[#asUnsignedInteger] -> [#usqInt].
+ [#asUnsignedIntegerPtr]-> [#'usqIntptr_t'].
[#asUnsignedLong] -> [#'unsigned long'].
[#asUnsignedLongLong] -> [#'unsigned long long'].
[#asVoidPointer] -> [#'void *'].
[#signedIntToLong] -> [#usqInt]. "c.f. generateSignedIntToLong:on:indent:"
[#signedIntToShort] -> [#usqInt]. "c.f. generateSignedIntToShort:on:indent:"
[#cCoerce:to:] -> [sendNode args last value].
[#cCoerceSimple:to:] -> [sendNode args last value].
[#sizeof:] -> [#'unsigned long']. "Technically it's a size_t but it matches unsigned long on target architectures so far..."
[#ifTrue:ifFalse:] -> [self typeForConditional: sendNode in: aTMethod].
[#ifFalse:ifTrue:] -> [self typeForConditional: sendNode in: aTMethod].
[#ifTrue:] -> [self typeForConditional: sendNode in: aTMethod].
[#ifFalse:] -> [self typeForConditional: sendNode in: aTMethod].
[#and:] -> [#sqInt].
[#or:] -> [#sqInt] }
otherwise: "If there /is/ a method for sel but its return type is as yet unknown it /mustn't/ be defaulted,
since on a subsequent pass its type may be computable. Only default unbound selectors."
[methodOrNil ifNotNil: [nil] ifNil: [typeIfNil]]]!
Item was changed:
----- Method: CCodeGenerator>>signedTypeForIntegralType: (in category 'type inference') -----
signedTypeForIntegralType: aCTypeString
(aCTypeString beginsWith: 'unsigned ') ifTrue:
[^aCTypeString allButFirst: 8].
(aCTypeString beginsWith: 'usq') ifTrue:
[^aCTypeString allButFirst].
+ aCTypeString = 'size_t' ifTrue: [^#usqIntptr_t].
+
self error: 'unknown type'.
^#long!
Item was changed:
----- Method: CCodeGenerator>>sizeOfIntegralCType: (in category 'inlining') -----
sizeOfIntegralCType: anIntegralCType "<String>"
"N.B. Only works for values for which isIntegralCType: answers true."
| prunedCType index |
(anIntegralCType beginsWith: 'register ') ifTrue:
[^self sizeOfIntegralCType: (anIntegralCType allButFirst: 9)].
prunedCType := (anIntegralCType beginsWith: 'unsigned ')
ifTrue: [(anIntegralCType allButFirst: 9) withBlanksTrimmed]
ifFalse: [(anIntegralCType beginsWith: 'signed ')
ifTrue: [(anIntegralCType allButFirst: 7) withBlanksTrimmed]
ifFalse: [anIntegralCType]].
+
^prunedCType asString caseOf: {
['sqLong'] -> [8].
['usqLong'] -> [8].
['long long'] -> [8].
+ ['sqInt'] -> [BytesPerOop].
+ ['usqInt'] -> [BytesPerOop].
+ ['sqIntptr_t'] -> [BytesPerWord].
+ ['usqIntptr_t'] -> [BytesPerWord].
- ['sqInt'] -> [BytesPerWord].
- ['usqInt'] -> [BytesPerWord].
['int'] -> [4].
['short'] -> [2].
['short int'] -> [2].
['char'] -> [1].
+ ['long'] -> [BytesPerWord]. "It's ambiguous on LLP64 and we'll later remove it"
+ ['size_t'] -> [BytesPerWord].
- ['long'] -> [BytesPerWord].
- ['size_t'] -> [BytesPerWord].
['pid_t'] -> [BytesPerWord].
}
otherwise:
[((anIntegralCType beginsWith: 'unsigned') "e.g. 'unsigned : 8'"
and: [(anIntegralCType includesAnyOf: '[*]') not
and: [(index := anIntegralCType indexOf: $:) > 0]])
ifTrue: [(Integer readFrom: (anIntegralCType copyFrom: index + 1 to: anIntegralCType size) withBlanksTrimmed readStream) + 7 // 8]
ifFalse: [self error: 'unrecognized integral type']]!
Item was added:
+ ----- Method: CogAbstractInstruction>>asIntegerPtr (in category 'coercion') -----
+ asIntegerPtr
+ <doNotGenerate>
+ ^self!
Item was added:
+ ----- Method: CogAbstractInstruction>>asUnsignedIntegerPtr (in category 'coercion') -----
+ asUnsignedIntegerPtr
+ <doNotGenerate>
+ ^self!
Item was changed:
----- Method: CogClass>>cCoerceSimple:to: (in category 'translation support') -----
cCoerceSimple: value to: cTypeString
<doNotGenerate>
"Type coercion for translation and simulation.
For simulation answer a suitable surrogate for the struct types"
^cTypeString caseOf:
{ [#'unsigned long'] -> [value].
[#'unsigned int'] -> [value].
[#sqInt] -> [value].
+ [#'sqIntptr_t'] -> [value].
+ [#'usqIntptr_t'] -> [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 added:
+ ----- Method: CogMethodSurrogate>>asIntegerPtr (in category 'accessing') -----
+ asIntegerPtr
+ "Answer the surrogate's adress. This is equivalent to a C cast to usqIntptr_t,
+ which is precisely what Slang generates for asIntegerPtr"
+ ^address!
Item was added:
+ ----- Method: CogMethodSurrogate>>asUnsignedIntegerPtr (in category 'accessing') -----
+ asUnsignedIntegerPtr
+ "Answer the surrogate's adress. This is equivalent to a C cast to usqIntptr_t,
+ which is precisely what Slang generates for asUnsignedIntegerPtr"
+ ^address!
Item was added:
+ ----- Method: CogSSBytecodeFixup>>asIntegerPtr (in category 'simulation support') -----
+ asIntegerPtr
+ <doNotGenerate>
+ ^self!
Item was added:
+ ----- Method: CogSSBytecodeFixup>>asUnsignedIntegerPtr (in category 'simulation support') -----
+ asUnsignedIntegerPtr
+ <doNotGenerate>
+ ^self!
Item was added:
+ ----- Method: CogStackPageSurrogate>>asIntegerPtr (in category 'accessing') -----
+ asIntegerPtr
+ ^address!
Item was added:
+ ----- Method: CogStackPageSurrogate>>asUnsignedIntegerPtr (in category 'accessing') -----
+ asUnsignedIntegerPtr
+ ^address!
Item was added:
+ ----- Method: Integer>>asIntegerPtr (in category '*VMMaker-interpreter simulator') -----
+ asIntegerPtr
+ ^self!
Item was added:
+ ----- Method: Integer>>asUnsignedIntegerPtr (in category '*VMMaker-interpreter simulator') -----
+ asUnsignedIntegerPtr
+ "Since the simulator deals with positive integers most of the time we assert that the receiver is greater than zero.
+ But one major exception is stack pointers in the StackInterpreterSimulator, which are negative. So don't fail
+ if the sender is a StackInterpreter and the receiver could be a stack pointer."
+ self >= 0 ifFalse:
+ [self assert: ((thisContext sender methodClass includesBehavior: StackInterpreter)
+ and: [thisContext sender receiver stackPages couldBeFramePointer: self])].
+ ^self!
Item was changed:
----- Method: InterpreterPlugin>>sizeof: (in category 'simulation support') -----
sizeof: objectSymbolOrClass
<doNotGenerate>
objectSymbolOrClass isInteger ifTrue:
[^interpreterProxy wordSize].
objectSymbolOrClass isSymbol ifTrue:
["In the simulator file handles are just integer indices into openFiles and so need
only be BytesPerWord big. But in the actual VM they are at least 5 words long."
objectSymbolOrClass == #SQFile ifTrue:
[^interpreterProxy wordSize * 5].
"SQSocket is typedef struct { int sessionID; int socketType; void *privateSocketPtr; } SQSocket"
objectSymbolOrClass == #SQSocket ifTrue:
[^8 + interpreterProxy wordSize].
"We assume the file offset type is always 64-bits."
objectSymbolOrClass == #squeakFileOffsetType ifTrue:
[^8].
(objectSymbolOrClass last == $*
or: [#long == objectSymbolOrClass
+ or: [#'unsigned long' == objectSymbolOrClass
+ or: [#'sqIntptr_t' == objectSymbolOrClass
+ or: [#'usqIntptr_t' == objectSymbolOrClass
+ or: [#'size_t' == objectSymbolOrClass]]]]]) ifTrue:
- or: [#'unsigned long' == objectSymbolOrClass]]) ifTrue:
[^interpreterProxy wordSize].
(#(usqInt sqInt) includes: objectSymbolOrClass) ifTrue:
[^interpreterProxy bytesPerOop]].
^super sizeof: objectSymbolOrClass!
Item was changed:
----- Method: SistaCogit>>picDataFor:Annotation:Mcpc:Bcpc:Method: (in category 'method introspection') -----
picDataFor: descriptor Annotation: isBackwardBranchAndAnnotation Mcpc: mcpc Bcpc: bcpc Method: cogMethodArg
<var: #descriptor type: #'BytecodeDescriptor *'>
<var: #mcpc type: #'char *'>
<var: #cogMethodArg type: #'void *'>
| annotation entryPoint tuple counter |
+ <var: #counter type: #usqInt>
- <var: #counter type: #'unsigned long'>
descriptor ifNil:
[^0].
descriptor isBranch ifTrue:
["it's a branch; conditional?"
(descriptor isBranchTrue or: [descriptor isBranchFalse]) ifTrue:
[counter := (self
cCoerce: ((self
cCoerceSimple: cogMethodArg
to: #'CogMethod *') counters)
+ to: #'usqInt *')
- to: #'unsigned long *')
at: counterIndex.
tuple := self picDataForCounter: counter at: bcpc + 1.
tuple = 0 ifTrue: [^PrimErrNoMemory].
objectMemory storePointer: introspectionDataIndex ofObject: introspectionData withValue: tuple.
introspectionDataIndex := introspectionDataIndex + 1.
counterIndex := counterIndex + 1].
^0].
annotation := isBackwardBranchAndAnnotation >> 1.
((self isPureSendAnnotation: annotation)
and: [entryPoint := backEnd callTargetFromReturnAddress: mcpc asUnsignedInteger.
entryPoint > methodZoneBase]) ifFalse: "send is not linked, or is not a send"
[^0].
self targetMethodAndSendTableFor: entryPoint "It's a linked send; find which kind."
annotation: annotation
into: [:targetMethod :sendTable| | methodClassIfSuper association |
methodClassIfSuper := nil.
sendTable = superSendTrampolines ifTrue:
[methodClassIfSuper := coInterpreter methodClassOf: (self cCoerceSimple: cogMethodArg to: #'CogMethod *') methodObject].
sendTable = directedSuperSendTrampolines ifTrue:
[association := backEnd literalBeforeInlineCacheTagAt: mcpc asUnsignedInteger.
methodClassIfSuper := objectRepresentation valueOfAssociation: association].
tuple := self picDataForSendTo: targetMethod
methodClassIfSuper: methodClassIfSuper
at: mcpc
bcpc: bcpc + 1].
tuple = 0 ifTrue: [^PrimErrNoMemory].
objectMemory storePointer: introspectionDataIndex ofObject: introspectionData withValue: tuple.
introspectionDataIndex := introspectionDataIndex + 1.
^0!
Item was changed:
----- Method: SistaCogit>>picDataForCounter:at: (in category 'method introspection') -----
picDataForCounter: counter at: bcpc
| executedCount tuple untakenCount |
+ <var: #counter type: #usqInt>
- <var: #counter type: #'unsigned long'>
tuple := objectMemory
eeInstantiateClassIndex: ClassArrayCompactIndex
format: objectMemory arrayFormat
numSlots: 3.
tuple = 0 ifTrue:
[^0].
self assert: CounterBytes = 4.
executedCount := initialCounterValue - (counter >> 16).
untakenCount := initialCounterValue - (counter bitAnd: 16rFFFF).
objectMemory
storePointerUnchecked: 0 ofObject: tuple withValue: (objectMemory integerObjectOf: bcpc);
storePointerUnchecked: 1 ofObject: tuple withValue: (objectMemory integerObjectOf: executedCount);
storePointerUnchecked: 2 ofObject: tuple withValue: (objectMemory integerObjectOf: untakenCount).
^tuple!
Item was changed:
----- Method: Spur32BitMemoryManager>>integerObjectOfCharacterObject: (in category 'immediates') -----
integerObjectOfCharacterObject: oop
"Immediate characters are unsigned"
+ ^(self cCoerceSimple: oop to: #usqInt) >> 1!
- ^(self cCoerceSimple: oop to: #'unsigned long') >> 1!
Item was changed:
----- Method: SpurMemoryManager class>>declareCVarsIn: (in category 'translation') -----
declareCVarsIn: aCCodeGenerator
self declareCAsOop: #( memory freeStart scavengeThreshold newSpaceStart newSpaceLimit pastSpaceStart
lowSpaceThreshold freeOldSpaceStart oldSpaceStart endOfMemory firstFreeChunk lastFreeChunk)
in: aCCodeGenerator.
self declareCAsUSqLong: (self allInstVarNames select: [:ivn| ivn endsWith: 'Usecs'])
in: aCCodeGenerator.
aCCodeGenerator
var: #freeListsMask type: #usqInt;
var: #freeLists type: #'sqInt *';
var: #objStackInvalidBecause type: #'char *';
var: #unscannedEphemerons type: #SpurContiguousObjStack;
var: #heapGrowthToSizeGCRatio type: #float;
var: #heapSizeAtPreviousGC type: #usqInt;
var: #totalFreeOldSpace type: #usqInt;
+ var: #maxOldSpaceSize type: #usqInt.
- var: #maxOldSpaceSize type: #'unsigned long'.
aCCodeGenerator
var: #remapBuffer
declareC: 'sqInt remapBuffer[RemapBufferSize + 1 /* ', (RemapBufferSize + 1) printString, ' */]'.
aCCodeGenerator
var: #extraRoots
declareC: 'sqInt *extraRoots[ExtraRootsSize + 1 /* ', (ExtraRootsSize + 1) printString, ' */]'!
Item was changed:
----- Method: SpurMemoryManager>>setMaxOldSpaceSize: (in category 'accessing') -----
setMaxOldSpaceSize: limit
+ <var: #limit type: #usqInt>
- <var: #limit type: #'unsigned long'>
maxOldSpaceSize := limit.
^0!
Item was changed:
----- Method: ThreadedFFIPlugin>>primitiveFFIIntegerAt (in category 'primitives') -----
primitiveFFIIntegerAt
"Answer a (signed or unsigned) n byte integer from the given byte offset
in the receiver, using the platform's endianness."
| isSigned byteSize byteOffset rcvr addr value mask valueOop |
<var: 'value' type: #usqLong>
<var: 'mask' type: #usqLong>
<export: true>
<inline: false>
isSigned := interpreterProxy booleanValueOf: (interpreterProxy stackValue: 0).
byteSize := interpreterProxy stackIntegerValue: 1.
byteOffset := interpreterProxy stackIntegerValue: 2.
rcvr := interpreterProxy stackObjectValue: 3.
interpreterProxy failed ifTrue:[^0].
(byteOffset > 0
and: [(byteSize between: 1 and: 8)
and: [(byteSize bitAnd: byteSize - 1) = 0 "a.k.a. isPowerOfTwo"]]) ifFalse:
[^interpreterProxy primitiveFail].
addr := self ffiAddressOf: rcvr startingAt: byteOffset size: byteSize.
interpreterProxy failed ifTrue:[^0].
byteSize <= 2
ifTrue:
[byteSize = 1
ifTrue: [value := self cCoerceSimple: (interpreterProxy byteAt: addr) to: #'unsigned char']
ifFalse: [value := self cCoerceSimple: (interpreterProxy shortAt: addr) to: #'unsigned short']]
ifFalse:
[byteSize = 4
ifTrue: [value := self cCoerceSimple: (interpreterProxy long32At: addr) to: #'unsigned int']
ifFalse: [value := interpreterProxy long64At: addr]].
byteSize < BytesPerWord
ifTrue:
[isSigned ifTrue: "sign extend value"
+ [mask := 1 asUnsignedLongLong << (byteSize * 8 - 1).
- [mask := 1 << (byteSize * 8 - 1).
value := (value bitAnd: mask-1) - (value bitAnd: mask)].
"note: byte/short (&long if BytesPerWord=8) never exceed SmallInteger range"
valueOop := interpreterProxy integerObjectOf: value]
ifFalse: "general 64 bit integer; note these never fail"
[isSigned
ifTrue:
[byteSize < 8 ifTrue: "sign extend value"
+ [mask := 1 asUnsignedLongLong << (byteSize * 8 - 1).
- [mask := 1 << (byteSize * 8 - 1).
value := (value bitAnd: mask-1) - (value bitAnd: mask)].
valueOop := interpreterProxy signed64BitIntegerFor: value]
ifFalse:[valueOop := interpreterProxy positive64BitIntegerFor: value]].
^interpreterProxy pop: 4 thenPush: valueOop!
Item was added:
+ ----- Method: UndefinedObject>>asIntegerPtr (in category '*VMMaker-interpreter simulator') -----
+ asIntegerPtr
+ ^self!
Item was added:
+ ----- Method: UndefinedObject>>asUnsignedIntegerPtr (in category '*VMMaker-interpreter simulator') -----
+ asUnsignedIntegerPtr
+ ^self!
Item was changed:
----- Method: VMClass>>sizeof: (in category 'translation support') -----
sizeof: objectSymbolOrClass
<doNotGenerate>
| index |
objectSymbolOrClass isInteger ifTrue:
[^self class objectMemoryClass wordSize].
+ (#(usqInt sqInt) includes: objectSymbolOrClass) ifTrue: [^self class objectMemoryClass bytesPerOop].
objectSymbolOrClass isSymbol ifTrue:
[(objectSymbolOrClass last == $*
+ or: [#(#long #'unsigned long' #'sqIntptr_t' #'usqIntptr_t' #'size_t') includes: objectSymbolOrClass]) ifTrue:
- or: [#long == objectSymbolOrClass
- or: [#'unsigned long' == objectSymbolOrClass]]) ifTrue:
[^self class objectMemoryClass wordSize].
index := #( #sqLong #usqLong #double
#int #'unsigned int' #float
#short #'unsigned short'
#char #'unsigned char' #'signed char')
indexOf: objectSymbolOrClass
ifAbsent:
+ [self error: 'unrecognized C type name'].
- [(#(usqInt sqInt) includes: objectSymbolOrClass) ifTrue: [^self class objectMemoryClass bytesPerOop].
- self error: 'unrecognized C type name'].
^#(8 8 8
4 4 4
2 2
1 1 1) at: index].
^(objectSymbolOrClass isBehavior
ifTrue: [objectSymbolOrClass]
ifFalse: [objectSymbolOrClass class])
alignedByteSizeOf: objectSymbolOrClass
forClient: self!
More information about the Vm-dev
mailing list