Custom Search
|
Date: December 31, 2006
From: Stephen Compall <s11@xxxxxxxxxxxxxx>
In-reply-to:
<4597F115.7030008@xxxxxxxxxxx>
References:
<1167539491.17849.24.camel@xxxxxxxxxxxxxxxxxx> <4597F115.7030008@xxxxxxxxxxx>
On Sun, 2006-12-31 at 18:19 +0100, Paolo Bonzini wrote: > This one seems wrong, you need "self start + source size - 1" IMO? Doh! > Except #primitive:, compilation of attributes is taken care by blocks > registered with the classes and returned by Class>>#pragmaHandlerFor: > (if it returns nil, the attribute has no compile-time semantics). With > the usual bugs due to lack of good unit tests... > > The blocks are evaluated passing the CompiledMethod and the attribute (a > Message), and their return value is nil or an error message. Well, this is better than ... reimplementing everything ... > > (Wondering what's causing the "duplicate variable name" warnings. Oh > > well, some other time, more testing) > > I get them too, let's see who gets it first. http://scompall.nocandysw.com/gst/varscope-and-dupExists.diff 2006-12-31 Stephen Compall <scompall@xxxxxxxxxxxxx> * compiler/STSymTable.st: Support nested scopes, warn on variable shadowing, and raise compiler error if variable duplicated at same scope level. The spurious 'duplicate variable name' warning was due to a boolean inversion. While looking for that I found something else that seemed odd: st> [UndefinedObject compile: 'scTest |a| a := 2. [:a | a] value. ^a'] on: Warning do: [:w | w messageText printNl. w resume]! 'duplicate variable name a' Object: STFileInParser new "<-0x4c24cba0>" error: Undefined variable 'a' referenced. I tested this in Squeak, which makes compilation fail for shadowing names. While this is just a change from compileWarning: to compileError:, I decided to add variable scope-sensitivity and shadowing instead, which seems to be what the builtin compiler does as well. With this patch: st> [UndefinedObject compile: 'scTest |a| a := 2. [:a | a] value. ^a'] on: Warning do: [:w | w messageText printNl. w resume]! 'variable ''a'' shadows another' > The attached patch may require some work to retrofit into your (patched) > 2.3 tree, but I will backport the entire set to my arch repository later. I would love to be working with arch, but...see <1166042207.19400.13.camel@xxxxxxxxxxxxxxxxxx>, or 'command-line-dependent compiler "error"' for more. -- Stephen Compall http://scompall.nocandysw.com/blog
signature.asc
Description: This is a digitally signed message part
_______________________________________________ help-smalltalk mailing list help-smalltalk@xxxxxxx http://lists.gnu.org/mailman/listinfo/help-smalltalk
Date: December 31, 2006
From: Mike Anderson <gnu-smalltalk@xxxxxxxxxxxxxxxxxxxx>
Well, I've taken the plunge and moved to 2.3.1 on account of having problems with sockets in 2.2. Having different problems with the web server in 2.3; I'll let you know more when I know more. Mike
--- Builtins.st.orig 2006-12-31 21:05:30.000000000 +0000
+++ Builtins.st 2006-12-31 21:05:49.000000000 +0000
@@ -1924,7 +1924,7 @@
anInteger isInteger
ifFalse: [ SystemExceptions.WrongClass signalOn: anInteger mustBe:
SmallInteger ].
- ^(self between: 0 and: 127)
+ ^(anInteger between: 0 and: 127)
ifTrue: [ self value: anInteger ]
ifFalse: [ SystemExceptions.ArgumentOutOfRange signalOn: anInteger
mustBeBetween: 0 and: 127 ]
!
_______________________________________________ help-smalltalk mailing list help-smalltalk@xxxxxxx http://lists.gnu.org/mailman/listinfo/help-smalltalk
Date: December 31, 2006
From: Paolo Bonzini <paolo.bonzini@xxxxxxxxxxx>
In-reply-to:
<1167458772.16047.38.camel@xxxxxxxxxxxxxxxxxx>
References:
<1167458772.16047.38.camel@xxxxxxxxxxxxxxxxxx>
Stephen Compall wrote:
I was getting instvar indexing conflicts (different classes would choose instvar 0 for different instvars) in Compiler until the attached tiny patch to STSymbolTable>>#declareEnvironment:. Iterating from the other end of the inheritance tree seems to be what is intended by the readOnly calculation semantics, anyway.
Applied the patch, and reworked the readOnly stuff to be correct. See the equivalent snippet of libgst/sym.c, where if the method is trusted all variables are read-write (in is_instance_variable_read_only).
@@ -157,18 +157,19 @@ addPool: poolDictionary
declareEnvironment: aBehavior
- | i readOnly |
+ | i canAlwaysStore inSandbox |
environment := aBehavior.
+ inSandbox := thisContext isUntrusted.
i := -1.
- readOnly := aBehavior isUntrusted not and: [ thisContext isUntrusted ].
- aBehavior withAllSuperclassesDo: [ :class |
- readOnly := readOnly and: [ class isUntrusted not ].
+ canAlwaysStore := aBehavior isUntrusted.
+ aBehavior withAllSuperclasses reverseDo: [ :class |
+ canAlwaysStore := canAlwaysStore and: [ class isUntrusted ].
class instVarNames do: [ :iv |
instVars at: iv asSymbol put: (STVariable
id: (i := i + 1)
scope: 0
- canStore: readOnly not).
+ canStore: (canAlwaysStore or: [ inSandbox not ])).
].
].
self declareGlobals
Paolo
Date: December 31, 2006
From: Paolo Bonzini <paolo.bonzini@xxxxxxxxxxx>
In-reply-to:
<1167455184.16047.32.camel@xxxxxxxxxxxxxxxxxx>
References:
<1167455184.16047.32.camel@xxxxxxxxxxxxxxxxxx>
Stephen Compall wrote:
I've been trying to load I18N with Compiler loaded in 2.3.1, using compiler-cascade.diff from earlier. (This patch works fine, by the way.) In STSymbolTable, bindingOf:for: (used for vars with paths) handles undeclared variables during fileIn as the builtin compiler does, but lookupPoolsFor: (used for vars without paths) does not. Attached is gst-lookupPoolsFor-undeclared.diff on compiler/STSymTable.st to handle this.
I applied it, except that I renamed lookupPoolsAndUndeclaredFor: to lookupBindingOf:
RBArrayConstructorNode>>#acceptVisitor: still sends #acceptArrayNode:, and RBProgramNodeVisitor's implementation of that descends into the SequenceNode, presumably invoking the aforementioned #finish. I don't know which way the renaming is going, so I just added acceptArrayNode: to STCompiler.
I renamed every acceptArrayNode: to acceptArrayConstructorNode: and applied the other part of the patch.
Thanks (next time also include ChangeLog entries)! Paolo
Date: December 31, 2006
From: Paolo Bonzini <paolo.bonzini@xxxxxxxxxxx>
In-reply-to:
<1167535913.17849.8.camel@xxxxxxxxxxxxxxxxxx>
References:
<1167535913.17849.8.camel@xxxxxxxxxxxxxxxxxx>
I'll assume that 0-index is intended, because that's what PositionableStream>>#segmentFrom:to: depends on in compiler/RBParser.st.
Yes, it's right.
On a related note, I found something else in kernel/FileDescr.st:
copyFrom: from to: to
"Answer the contents of the file between the two given positions"
| offset fromPos toPos savePos |
from > to ifTrue: [
from = to + 1 ifTrue: [ ^self species new ].
^SystemExceptions.ArgumentOutOfRange signalOn: from mustBeBetween: 1
and: to + 1
].
savePos := self fileOp: 5.
^[
self position: fromPos.
self next: toPos - fromPos + 1
] ensure: [
self position: savePos
]
How do offset, fromPos, and toPos get set in this method?
This is blatantly wrong... s/Pos//g and remove the three temporaries. Paolo
Date: December 31, 2006
From: Paolo Bonzini <paolo.bonzini@xxxxxxxxxxx>
In-reply-to:
<1167539491.17849.24.camel@xxxxxxxxxxxxxxxxxx>
References:
<1167539491.17849.24.camel@xxxxxxxxxxxxxxxxxx>
Stephen Compall wrote:
http://scompall.nocandysw.com/gst/gst-methodAttributes-comp.diff puts in place a simple framework for compiling attributes like <cCall:...> and <primitive:...> in STCompiler. It also includes some fixes for RBMethodNode>>#start, #stop
This one seems wrong, you need "self start + source size - 1" IMO? and PositionableStream>>#copyFrom:to:, as
these are necessary for stream-based compilation tests. It assumes compiler-cascade.diff is applied.
Yeah, I committed it.
This does not include actual compilation of any attribute tags, but it does parse them and warn when a given type is unimplemented.
Except #primitive:, compilation of attributes is taken care by blocks registered with the classes and returned by Class>>#pragmaHandlerFor: (if it returns nil, the attribute has no compile-time semantics). With the usual bugs due to lack of good unit tests...
The blocks are evaluated passing the CompiledMethod and the attribute (a Message), and their return value is nil or an error message.
It will probably break on filing in because FileSegment can be used for RBMethodNode's source instvar, which doesn't support copyFrom:to:.
Then let's add it. :-)
(Wondering what's causing the "duplicate variable name" warnings. Oh well, some other time, more testing)
I get them too, let's see who gets it first.The attached patch may require some work to retrofit into your (patched) 2.3 tree, but I will backport the entire set to my arch repository later.
Thanks, Paolo
* looking for bonzini@xxxxxxxxxxxxxx/smalltalk--devo--2.2--patch-231 to compare
with
* comparing to bonzini@xxxxxxxxxxxxxx/smalltalk--devo--2.2--patch-231
M compiler/RBParseNodes.st
M compiler/RBParser.st
M compiler/STCompiler.st
M kernel/Class.st
M kernel/FileSegment.st
M kernel/PosStream.st
* modified files
--- orig/compiler/RBParseNodes.st
+++ mod/compiler/RBParseNodes.st
@@ -953,8 +953,11 @@ children
^self arguments copyWith: self body!
primitiveSources
+ | offset |
+ offset := self start - 1.
^self tags
- collect: [:each | self source copyFrom: each first to: each last]!
+ collect: [:each | self source copyFrom: each first - offset
+ to: each last - offset]!
isBinary
^(self isUnary or: [self isKeyword]) not!
@@ -991,10 +994,13 @@ source: anObject
source := anObject!
start
+ (selectorParts notNil and: [ selectorParts first start notNil ])
+ ifTrue: [ ^selectorParts first start ].
+ body start isNil ifFalse: [ ^body start ].
^1!
stop
- ^source size!
+ ^self start + source size - 1!
tags
^tags isNil ifTrue: [#()] ifFalse: [tags]!
--- orig/compiler/RBParser.st
+++ mod/compiler/RBParser.st
@@ -97,6 +97,9 @@ scanner: aScanner
addCommentsTo: aNode
aNode comments: scanner getComments!
+currentToken
+ ^currentToken!
+
nextToken
^nextToken isNil
ifTrue: [nextToken := scanner next]
@@ -153,6 +156,14 @@ parseBinaryMessage
whileTrue: [node := self parseBinaryMessageWith: node].
^node!
+parseBinaryMessageNoGreater
+ | node |
+ node := self parseUnaryMessage.
+
+ [ currentToken isBinary and: [currentToken value ~~ #>] ]
+ whileTrue: [node := self parseBinaryMessageWith: node].
+ ^node!
+
parseBinaryMessageWith: aNode
| binaryToken |
binaryToken := currentToken.
--- orig/compiler/STCompiler.st
+++ mod/compiler/STCompiler.st
@@ -419,7 +419,7 @@ acceptSequenceNode: node
!STCompiler methodsFor: 'visiting RBMethodNodes'!
acceptMethodNode: node
- | statements method |
+ | statements method attributes |
node body addSelfReturn.
depth := maxDepth := 0.
@@ -429,11 +429,12 @@ acceptMethodNode: node
self undeclareArgumentsAndTemporaries: node.
symTable finish.
+ attributes := self compileMethodAttributes: node primitiveSources.
method := CompiledMethod
literals: symTable literals
numArgs: node arguments size
numTemps: node body temporaries size
- attributes: #()
+ attributes: attributes
bytecodes: bytecodes contents
depth: maxDepth + node body temporaries size + node arguments size.
@@ -442,6 +443,12 @@ acceptMethodNode: node
methodClass: symTable environment;
selector: node selector.
+ method attributesDo: [ :ann || handler error |
+ handler := symTable environment pragmaHandlerFor: ann selector.
+ handler notNil ifTrue: [
+ error := handler value: method value: ann.
+ error notNil ifTrue: [ self compileError: error ] ] ].
+
^method
! !
@@ -934,4 +941,44 @@ compileStoreTemporary: number scopes: ou
arg: number
! !
+"--------------------------------------------------------------------"
+
+!STCompiler methodsFor: 'compiling method attributes'!
+
+compileMethodAttributes: attributes
+ ^attributes asArray collect: [ :each |
+ self compileAttribute: (RBScanner on: each readStream) ]!
+
+scanTokenFrom: scanner
+ scanner atEnd
+ ifTrue: [^self compileError: 'method attributes must end with ''>'''].
+ ^scanner next!
+
+compileAttribute: scanner
+ | currentToken selectorBuilder selector arguments parser node |
+ currentToken := self scanTokenFrom: scanner.
+ (currentToken isBinary and: [currentToken value == #<])
+ ifFalse: [^self compileError:
+ 'method attributes must begin with ''<'''].
+
+ selectorBuilder := WriteStream on: String new.
+ arguments := WriteStream on: Array new.
+ currentToken := self scanTokenFrom: scanner.
+ [ currentToken isBinary and: [currentToken value == #>] ] whileFalse: [
+ currentToken isKeyword
+ ifFalse: [^self compileError: 'keyword expected in method
attribute'].
+ selectorBuilder nextPutAll: currentToken value.
+
+ parser := RBParser new.
+ parser errorBlock: parser errorBlock.
+ parser scanner: scanner.
+ node := parser parseBinaryMessageNoGreater.
+ node := RBSequenceNode statements: {node}.
+ arguments nextPut: (self class evaluate: node parser: parser).
+ currentToken := parser currentToken.
+ ].
+
+ selector := selectorBuilder contents asSymbol.
+ ^Message selector: selector arguments: arguments contents! !
+
STCompiler initialize!
--- orig/kernel/Class.st
+++ mod/kernel/Class.st
@@ -496,7 +496,7 @@ registerHandler: aBlock forPragma: pragm
pragmaHandlerFor: aSymbol
| handler |
pragmaHandlers isNil ifFalse: [
- handler := self pragmaHandlers at: aSymbol ifAbsent: [ nil ]
+ handler := pragmaHandlers at: aSymbol ifAbsent: [ nil ].
handler isNil ifFalse: [ ^handler ].
].
self superclass isNil ifFalse: [
--- orig/kernel/FileSegment.st
+++ mod/kernel/FileSegment.st
@@ -70,6 +70,25 @@ on: aFile startingAt: startPos for: size
!FileSegment methodsFor: 'basic'!
+copyFrom: from to: to
+ "Answer a String containing the given subsegment of the file. As for
+ streams, from and to are 0-based."
+ (to between: 0 and: size - 1) ifFalse: [
+ ^SystemExceptions.ArgumentOutOfRange
+ signalOn: to
+ mustBeBetween: 0
+ and: size - 1 ].
+ (from between: 0 and: to) ifFalse: [
+ from = to + 1 ifTrue: [ ^self species new ].
+ ^SystemExceptions.ArgumentOutOfRange
+ signalOn: from
+ mustBeBetween: 0
+ and: to + 1 ].
+
+ ^self withFileDo: [ :fileStream |
+ fileStream copyFrom: startPos + from to: startPos + to ]
+!
+
asString
"Answer a String containing the required segment of the file"
^self withFileDo: [ :fileStream |
@@ -139,6 +158,10 @@ hash
!FileSegment methodsFor: 'private'!
+species
+ ^String
+!
+
getFile
^file
!
_______________________________________________ help-smalltalk mailing list help-smalltalk@xxxxxxx http://lists.gnu.org/mailman/listinfo/help-smalltalk
Date: December 31, 2006
From: Stephen Compall <s11@xxxxxxxxxxxxxx>
http://scompall.nocandysw.com/gst/gst-methodAttributes-comp.diff puts in place a simple framework for compiling attributes like <cCall:...> and <primitive:...> in STCompiler. It also includes some fixes for RBMethodNode>>#start, #stop and PositionableStream>>#copyFrom:to:, as these are necessary for stream-based compilation tests. It assumes compiler-cascade.diff is applied. This does not include actual compilation of any attribute tags, but it does parse them and warn when a given type is unimplemented. It will probably break on filing in because FileSegment can be used for RBMethodNode's source instvar, which doesn't support copyFrom:to:. I am deciding whether having RBMethodNode>>#primitiveSources extract the source with asString on each call, saving the result in the source instvar, or something else would be the best solution. Quick test, with Compiler loaded: st> [UndefinedObject compile: 'float3: a arg: b arg: c <cCall: ''s11_float3'' returning: #int args: #(#float #float #float)>'] on: Warning do: [:w | w messageText displayNl. w resume]! duplicate variable name a duplicate variable name b duplicate variable name c <#cCall:returning:args:> tag not yet implemented (Wondering what's causing the "duplicate variable name" warnings. Oh well, some other time, more testing) -- Stephen Compall http://scompall.nocandysw.com/blog
signature.asc
Description: This is a digitally signed message part
_______________________________________________ help-smalltalk mailing list help-smalltalk@xxxxxxx http://lists.gnu.org/mailman/listinfo/help-smalltalk
Date: December 31, 2006
From: Stephen Compall <s11@xxxxxxxxxxxxxx>
In 2.3.1 with compiler-cascade.diff and the 3 diffs I posted yesterday
and today, I noticed that FileStream>>#copyFrom:to: uses 0-index,
whereas PositionableStream>>#copyFrom:to: uses 1-index.
st> | fs |
fs := FileStream fopen: '/home/sirian/TODO' mode: FileStream read.
[(fs copyFrom: 1 to: 3) printNl] ensure: [fs close]!
' To'
st> ('* Today' readStream copyFrom: 1 to: 3) printNl!
'* T'
(/home/sirian/TODO starts with '* Today:')
I'll assume that 0-index is intended, because that's what
PositionableStream>>#segmentFrom:to: depends on in compiler/RBParser.st.
On a related note, I found something else in kernel/FileDescr.st:
copyFrom: from to: to
"Answer the contents of the file between the two given positions"
| offset fromPos toPos savePos |
from > to ifTrue: [
from = to + 1 ifTrue: [ ^self species new ].
^SystemExceptions.ArgumentOutOfRange signalOn: from mustBeBetween: 1
and: to + 1
].
savePos := self fileOp: 5.
^[
self position: fromPos.
self next: toPos - fromPos + 1
] ensure: [
self position: savePos
]
How do offset, fromPos, and toPos get set in this method?
--
Stephen Compall
http://scompall.nocandysw.com/blog
signature.asc
Description: This is a digitally signed message part
_______________________________________________ help-smalltalk mailing list help-smalltalk@xxxxxxx http://lists.gnu.org/mailman/listinfo/help-smalltalk
Date: December 30, 2006
From: Paolo Bonzini <paolo.bonzini@xxxxxxxxxxx>
In-reply-to:
<5.2.0.9.0.20061229152503.01d54cb8@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>
References:
<5.2.0.9.0.20061229152503.01d54cb8@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>
J Pfersich wrote:
Will all these changes be in 2.3.2 or 2.4?
2.4 (3.0?) :-) Paolo
Date: December 30, 2006
From: Stephen Compall <s11@xxxxxxxxxxxxxx>
I was getting instvar indexing conflicts (different classes would choose instvar 0 for different instvars) in Compiler until the attached tiny patch to STSymbolTable>>#declareEnvironment:. Iterating from the other end of the inheritance tree seems to be what is intended by the readOnly calculation semantics, anyway. -- Stephen Compall http://scompall.nocandysw.com/blog
gst-reverse-instVar-indexing.diff
Description: Text Data
_______________________________________________ help-smalltalk mailing list help-smalltalk@xxxxxxx http://lists.gnu.org/mailman/listinfo/help-smalltalk
Date: December 30, 2006
From: Stephen Compall <s11@xxxxxxxxxxxxxx>
I've been trying to load I18N with Compiler loaded in 2.3.1, using
compiler-cascade.diff from earlier. (This patch works fine, by the
way.)
In STSymbolTable, bindingOf:for: (used for vars with paths) handles
undeclared variables during fileIn as the builtin compiler does, but
lookupPoolsFor: (used for vars without paths) does not. Attached is
gst-lookupPoolsFor-undeclared.diff on compiler/STSymTable.st to handle
this.
Then, I ran into what seemed to be a premature send of
STSymbolTable>>#finish (as #() cannot grow). Test:
st> UndefinedObject compile: 'scTest: aV and: bV | what | what := {aV. bV}.
self strftime: what format: aV readStream on: bV'!
Object: Array new: 0 "<-0x4c5c9288>" error: Invalid index 1: index out of range
SystemExceptions.IndexOutOfRange(Smalltalk.Exception)>>#signal
SystemExceptions.IndexOutOfRange class>>#signalOn:withIndex:
Smalltalk.Array(Smalltalk.Object)>>#checkIndexableBounds:put:
Smalltalk.Array(Smalltalk.Object)>>#at:put:
[] in STInST.STLiteralsTable>>#addLiteral:
RBArrayConstructorNode>>#acceptVisitor: still sends #acceptArrayNode:,
and RBProgramNodeVisitor's implementation of that descends into the
SequenceNode, presumably invoking the aforementioned #finish.
I don't know which way the renaming is going, so I just added
acceptArrayNode: to STCompiler. Then I found that
acceptArrayConstructorNode: was storing in 1,2,3 instead of 0,1,2 for
this little test: 'scTest ^{1. 2. 3}', so I shifted that back. Both are
in gst-arrayCtor.diff on compiler/STCompiler.st.
Now I can load I18N with Compiler!
--
Stephen Compall
http://scompall.nocandysw.com/blog
gst-lookupPoolsFor-undeclared.diff
Description: Text Data
gst-arrayCtor.diff
Description: Text Data
signature.asc
Description: This is a digitally signed message part
_______________________________________________ help-smalltalk mailing list help-smalltalk@xxxxxxx http://lists.gnu.org/mailman/listinfo/help-smalltalk
Date: December 29, 2006
From: J Pfersich <smalltalker2@xxxxxxx>
In-reply-to:
<45940862.5010307@xxxxxxxxxxx>
References:
<45940862.5010307@xxxxxxxxxxx>
Will all these changes be in 2.3.2 or 2.4? At 07:09 PM 12/28/2006 +0100, Paolo Bonzini wrote:
Ok, we are done. With this patch, we avoid doing useless work to fill the primitive table, and the last 10% separating GNU Smalltalk from Ruby (more or less) is covered. I may give a try at removing the final allInstancesDo: call upon quit, but that's faster quit (not faster startup!).Anyway, now hello world is 4-5 times faster than when I started. Paolo* looking for bonzini@xxxxxxxxxxxxxx/smalltalk--devo--2.2--patch-227 to compare with* comparing to bonzini@xxxxxxxxxxxxxx/smalltalk--devo--2.2--patch-227 M libgst/ChangeLog M libgst/genpr-parse.c M libgst/genpr-parse.h M libgst/interp.h M libgst/dict.c M libgst/save.c M libgst/dict.h M libgst/genpr-parse.y * modified files --- orig/libgst/ChangeLog +++ mod/libgst/ChangeLog @@ -1,5 +1,18 @@ 2006-12-28 Paolo Bonzini <bonzini@xxxxxxx> + * libgst/dict.c: Change _gst_init_dictionary_on_image_load to be + whether the primitive table's checksum is ok. If it is, just copy + the default primitive table just like in _gst_init_dictionary. + * libgst/dict.h: Adjust for above change. + * libgst/genpr-parse.y: Compute MD5 of DEF_FIL as checksum and + print it. + * libgst/interp.h: Declare _gst_primitives_md5.+ * libgst/save.c: Save its contents, and compare it to pass the new flag+ to _gst_init_dictionary_on_image_load. Move checks from load_snapshot + to load_file_version. + +2006-12-28 Paolo Bonzini <bonzini@xxxxxxx> + * libgst/gstpriv.h: Remove F_FREE. * libgst/oop.c: Remove loops setting flags to F_FREE. Set flags to 0 instead of F_FREE elsewhere. --- orig/libgst/dict.c +++ mod/libgst/dict.c @@ -1223,7 +1223,7 @@ create_class (const class_definition *ci mst_Boolean -_gst_init_dictionary_on_image_load (size_t numOOPs) +_gst_init_dictionary_on_image_load (mst_Boolean prim_table_matches) { const class_definition *ci; @@ -1259,7 +1259,12 @@ _gst_init_dictionary_on_image_load (size /* Important: this is called *after* _gst_init_symbols fills in _gst_vm_primitives_symbol! */ - prepare_primitive_numbers_table (); + if (prim_table_matches) + memcpy (_gst_primitive_table, _gst_default_primitive_table, + sizeof (_gst_primitive_table)); + else + prepare_primitive_numbers_table (); + init_runtime_objects (); return (true); } --- orig/libgst/dict.h +++ mod/libgst/dict.h @@ -603,10 +603,10 @@ extern void _gst_set_oop_bytes (OOP byte extern void _gst_free_cobject (OOP cObjOOP) ATTRIBUTE_HIDDEN; -/* Loads the contents of the global variable from the Smalltalk - dictionary after NUMOOPS objects have been loaded from an - image. */ -extern mst_Boolean _gst_init_dictionary_on_image_load (size_t numOOPs) +/* Loads the contents of the global variables from the Smalltalk dictionary + after an image has been restored. PRIM_TABLE_MATCHES if true if the + table of primitives is already set up correctly. */+extern mst_Boolean _gst_init_dictionary_on_image_load (mst_Boolean prim_table_matches)ATTRIBUTE_HIDDEN; /* Transforms a primitive name into a primitive index, looking up --- orig/libgst/genpr-parse.c +++ mod/libgst/genpr-parse.c @@ -89,6 +89,7 @@ #line 52 "genpr-parse.y" #include "genprims.h" +#include "md5.h" /* This program finds declarations of the form: @@ -169,14 +170,14 @@ static string_list *current_ids; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 117 "genpr-parse.y" +#line 118 "genpr-parse.y" { Filament *fil; char *text; int id; } /* Line 193 of yacc.c. */ -#line 180 "../../libgst/genpr-parse.c" +#line 181 "../../libgst/genpr-parse.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -189,7 +190,7 @@ typedef union YYSTYPE /* Line 216 of yacc.c. */ -#line 193 "../../libgst/genpr-parse.c" +#line 194 "../../libgst/genpr-parse.c" #ifdef short # undef short @@ -479,9 +480,9 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 140, 140, 139, 148, 154, 153, 166, 171, 177, - 182, 188, 196, 201, 210, 213, 220, 219, 232, 236, - 241, 240 + 0, 141, 141, 140, 149, 155, 154, 167, 172, 178, + 183, 189, 197, 202, 211, 214, 221, 220, 233, 237, + 242, 241 }; #endif @@ -1402,27 +1403,27 @@ yyreduce: switch (yyn) { case 2: -#line 140 "genpr-parse.y" +#line 141 "genpr-parse.y" { filprintf (stmt_fil, "#line %d \"prims.def\"\n{", yylineno); } break; case 3: -#line 144 "genpr-parse.y" +#line 145 "genpr-parse.y" { free_data (); } break; case 4: -#line 148 "genpr-parse.y" +#line 149 "genpr-parse.y" { } break; case 5: -#line 154 "genpr-parse.y" +#line 155 "genpr-parse.y" { current_id = 0; current_func_name = strdup ((yyvsp[(2) - (2)].text)); @@ -1432,13 +1433,13 @@ yyreduce: break; case 6: -#line 161 "genpr-parse.y" +#line 162 "genpr-parse.y" { } break; case 7: -#line 167 "genpr-parse.y" +#line 168 "genpr-parse.y" {gen_prim_id (current_func_name, (yyvsp[(1) - (2)].id), (yyvsp[(2) - (2)].text));free ((yyvsp[(2) - (2)].text)); @@ -1446,27 +1447,27 @@ yyreduce: break; case 8: -#line 172 "genpr-parse.y" +#line 173 "genpr-parse.y" { } break; case 9: -#line 178 "genpr-parse.y" +#line 179 "genpr-parse.y" { (yyval.id) = strtoul ((yyvsp[(2) - (2)].text), NULL, 10); } break; case 10: -#line 182 "genpr-parse.y" +#line 183 "genpr-parse.y" { (yyval.id) = current_id--; } break; case 11: -#line 189 "genpr-parse.y" +#line 190 "genpr-parse.y" { (yyval.text) = fildelete ((yyvsp[(2) - (3)].fil)); strupr ((yyval.text)); @@ -1474,7 +1475,7 @@ yyreduce: break; case 12: -#line 197 "genpr-parse.y" +#line 198 "genpr-parse.y" { (yyval.fil) = filnew ("PRIM_", 5); filcat ((yyval.fil), (yyvsp[(1) - (1)].text)); @@ -1482,7 +1483,7 @@ yyreduce: break; case 13: -#line 202 "genpr-parse.y" +#line 203 "genpr-parse.y" { (yyval.fil) = (yyvsp[(1) - (3)].fil); filcat ((yyval.fil), " | PRIM_"); @@ -1491,26 +1492,26 @@ yyreduce: break; case 14: -#line 211 "genpr-parse.y" +#line 212 "genpr-parse.y" { } break; case 15: -#line 214 "genpr-parse.y" +#line 215 "genpr-parse.y" { } break; case 16: -#line 220 "genpr-parse.y" +#line 221 "genpr-parse.y" { (yyval.text) = strdup((yyvsp[(2) - (2)].text)); } break; case 17: -#line 224 "genpr-parse.y" +#line 225 "genpr-parse.y" {gen_prim_id ((yyvsp[(3) - (5)].text), (yyvsp[(4) - (5)].id), (yyvsp[(5) - (5)].text));free ((yyvsp[(3) - (5)].text)); @@ -1519,14 +1520,14 @@ yyreduce: break; case 18: -#line 233 "genpr-parse.y" +#line 234 "genpr-parse.y" { filprintf (stmt_fil, "%d", (yyvsp[(2) - (2)].id)); } break; case 20: -#line 241 "genpr-parse.y" +#line 242 "genpr-parse.y" { (yyval.id) = lookup_prim_id ((yyvsp[(3) - (3)].text)); if ((yyval.id) == NOT_FOUND) @@ -1535,7 +1536,7 @@ yyreduce: break; case 21: -#line 247 "genpr-parse.y" +#line 248 "genpr-parse.y" { (yyval.id) = (yyvsp[(4) - (5)].id); literal_fil = stmt_fil; @@ -1544,7 +1545,7 @@ yyreduce: /* Line 1267 of yacc.c. */ -#line 1548 "../../libgst/genpr-parse.c" +#line 1549 "../../libgst/genpr-parse.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -1758,7 +1759,7 @@ yyreturn: } -#line 253 "genpr-parse.y" +#line 254 "genpr-parse.y" void @@ -1865,12 +1866,16 @@ void output() { char *proto, *stmt, *def; + unsigned int md5[16 / sizeof (int)]; + gen_proto ("VMpr_HOLE"); proto = fildelete (proto_fil); stmt = fildelete (stmt_fil); def = fildelete (def_fil); + md5_buffer (def, strlen (def), md5); + printf ("%s\n" "%s\n" "intptr_t\n" @@ -1884,6 +1889,8 @@ output() " PRIM_FAILED;\n" "}\n" "\n" + "int _gst_primitives_md5[4] = { 0x%x, 0x%x, 0x%x, 0x%x };\n" + "\n" "void\n" "_gst_init_primitives()\n" "{\n" @@ -1898,7 +1905,10 @@ output() " _gst_default_primitive_table[i].func = VMpr_HOLE;\n" " }\n" "}\n" - "\n", proto, stmt, def, prim_no + 1); + "\n", + proto, stmt, + md5[0], md5[1], md5[2], md5[3], + def, prim_no + 1); free (proto); free (stmt); --- orig/libgst/genpr-parse.h +++ mod/libgst/genpr-parse.h @@ -60,7 +60,7 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 117 "genpr-parse.y" +#line 118 "genpr-parse.y" { Filament *fil; char *text; --- orig/libgst/genpr-parse.y +++ mod/libgst/genpr-parse.y @@ -51,6 +51,7 @@ %{ #include "genprims.h" +#include "md5.h" /* This program finds declarations of the form: @@ -356,12 +357,16 @@ void output() { char *proto, *stmt, *def; + unsigned int md5[16 / sizeof (int)]; + gen_proto ("VMpr_HOLE"); proto = fildelete (proto_fil); stmt = fildelete (stmt_fil); def = fildelete (def_fil); + md5_buffer (def, strlen (def), md5); + printf ("%s\n" "%s\n" "intptr_t\n" @@ -375,6 +380,8 @@ output() " PRIM_FAILED;\n" "}\n" "\n" + "int _gst_primitives_md5[4] = { 0x%x, 0x%x, 0x%x, 0x%x };\n" + "\n" "void\n" "_gst_init_primitives()\n" "{\n" @@ -389,7 +396,10 @@ output() " _gst_default_primitive_table[i].func = VMpr_HOLE;\n" " }\n" "}\n" - "\n", proto, stmt, def, prim_no + 1); + "\n", + proto, stmt, + md5[0], md5[1], md5[2], md5[3], + def, prim_no + 1); free (proto); free (stmt); --- orig/libgst/interp.h +++ mod/libgst/interp.h @@ -542,6 +542,11 @@ prim_table_entry; #define PRIM_RETURN_SMALL_INTEGER 0x0100 /* 31 or 63 bits */ #define PRIM_RETURN_SMALL_SMALLINTEGER 0x0300 /* 30 or 62 bits */ +/* The checksum of the table of primitive numbers. Right now it is an MD5, + computed from part of the C source code of prims.inl. We compare it when + loading an image, to avoid having to reload the primitive table. */ +extern int _gst_primitives_md5[4]; + /* The table of functions that implement the primitives. */ extern prim_table_entry _gst_primitive_table[NUM_PRIMITIVES]; extern prim_table_entry _gst_default_primitive_table[NUM_PRIMITIVES]; --- orig/libgst/save.c +++ mod/libgst/save.c @@ -112,6 +112,7 @@ typedef struct save_file_header size_t space_grow_rate; size_t num_free_oops; intptr_t ot_base; + int prim_table_md5[4]; /* checksum for the primitive table */ } save_file_header; @@ -212,8 +213,8 @@ static void save_file_version (int image /* This function loads into HEADERP the header of the image file without checking its validity. This data is loaded from the IMAGEFD file descriptor. */ -static void load_file_version (int imageFd, - save_file_header * headerp); +static mst_Boolean load_file_version (int imageFd, + save_file_header * headerp); /* This function walks the OOP table and converts all the relative addresses for the instance variables to absolute ones. */ @@ -423,6 +424,8 @@ save_file_version (int imageFd, struct s headerp->grow_threshold_percent = _gst_mem.grow_threshold_percent; headerp->space_grow_rate = _gst_mem.space_grow_rate; headerp->ot_base = (intptr_t) _gst_mem.ot_base;+ memcpy (&headerp->prim_table_md5, _gst_primitives_md5, sizeof (_gst_primitives_md5));+ buffer_write (imageFd, headerp, sizeof (save_file_header)); } @@ -451,34 +454,11 @@ mst_Boolean load_snapshot (int imageFd) { save_file_header header; + int prim_table_matches; buffer_read_init (imageFd, READ_BUFFER_SIZE); - load_file_version (imageFd, &header); - if (strcmp (header.signature, SIGNATURE)) - return (false); - - /* different sizeof(PTR) not supported */ - if (FLAG_CHANGED (header.flags, SLOT_SIZE_FLAG)) - return (false); - - if UNCOMMON ((wrong_endianness = - FLAG_CHANGED (header.flags, ENDIANNESS_FLAG))) - { - header.oopTableSize = BYTE_INVERT (header.oopTableSize); - header.edenSpaceSize = BYTE_INVERT (header.edenSpaceSize); - header.survSpaceSize = BYTE_INVERT (header.survSpaceSize); - header.oldSpaceSize = BYTE_INVERT (header.oldSpaceSize);- header.big_object_threshold = BYTE_INVERT (header.big_object_threshold); - header.grow_threshold_percent = BYTE_INVERT (header.grow_threshold_percent);- header.space_grow_rate = BYTE_INVERT (header.space_grow_rate); - header.version = BYTE_INVERT (header.version); - header.num_free_oops = BYTE_INVERT (header.num_free_oops); - header.ot_base = BYTE_INVERT (header.ot_base); - } - - /* check for version mismatch; if so this image file is invalid */ - if (header.version > VERSION_REQUIRED) - return (false); + if (!load_file_version (imageFd, &header)) + return false; #ifdef SNAPSHOT_TRACE printf ("After loading header: %lld\n", file_pos + buf_pos); @@ -510,7 +490,9 @@ load_snapshot (int imageFd) if (ot_delta) restore_all_pointer_slots (); - if (_gst_init_dictionary_on_image_load (num_used_oops)) + prim_table_matches = !memcmp (header.prim_table_md5, _gst_primitives_md5, + sizeof (_gst_primitives_md5)); + if (_gst_init_dictionary_on_image_load (prim_table_matches)) { #ifdef SNAPSHOT_TRACE _gst_dump_oop_table (); @@ -521,19 +503,47 @@ load_snapshot (int imageFd) return (false); } -void +mst_Boolean load_file_version (int imageFd, save_file_header * headerp) { buffer_read (imageFd, headerp, sizeof (save_file_header)); + if (strcmp (headerp->signature, SIGNATURE)) + return (false); + + /* different sizeof(PTR) not supported */ + if (FLAG_CHANGED (headerp->flags, SLOT_SIZE_FLAG)) + return (false); + + if UNCOMMON ((wrong_endianness = + FLAG_CHANGED (headerp->flags, ENDIANNESS_FLAG))) + { + headerp->oopTableSize = BYTE_INVERT (headerp->oopTableSize); + headerp->edenSpaceSize = BYTE_INVERT (headerp->edenSpaceSize); + headerp->survSpaceSize = BYTE_INVERT (headerp->survSpaceSize); + headerp->oldSpaceSize = BYTE_INVERT (headerp->oldSpaceSize);+ headerp->big_object_threshold = BYTE_INVERT (headerp->big_object_threshold); + headerp->grow_threshold_percent = BYTE_INVERT (headerp->grow_threshold_percent);+ headerp->space_grow_rate = BYTE_INVERT (headerp->space_grow_rate); + headerp->version = BYTE_INVERT (headerp->version); + headerp->num_free_oops = BYTE_INVERT (headerp->num_free_oops); + headerp->ot_base = BYTE_INVERT (headerp->ot_base); + headerp->prim_table_md5[0] = BYTE_INVERT (headerp->prim_table_md5[0]); + headerp->prim_table_md5[1] = BYTE_INVERT (headerp->prim_table_md5[1]); + headerp->prim_table_md5[2] = BYTE_INVERT (headerp->prim_table_md5[2]); + headerp->prim_table_md5[3] = BYTE_INVERT (headerp->prim_table_md5[3]); + } + + /* check for version mismatch; if so this image file is invalid */ + if (headerp->version > VERSION_REQUIRED) + return (false); + + return (true); } void load_oop_table (int imageFd) { - OOP oop; - int i; - /* Load in the valid OOP slots from previous dump. The others are already initialized to free (0). */ buffer_read (imageFd, _gst_mem.ot, sizeof (struct oop_s) * num_used_oops); _______________________________________________ help-smalltalk mailing list help-smalltalk@xxxxxxx http://lists.gnu.org/mailman/listinfo/help-smalltalk
Date: December 29, 2006
From: Brad Watson <whitebearded1@xxxxxxxxx>
No joy with the CVS as-of 12/29/2006 0800 PST .... gcc -g -O2 -Wall -Wno-strict-aliasing -Wno-switch -fno-gcse -fstrict-aliasing -Wwrite-strings -Wdeclaration-after-statement -Wno-format -Wpointer-arith -Wno-pointer-sign -o gst main.o -Wl,--export-dynamic libgst/.libs/libgst.a -ldl -lreadline /usr/lib/libgmp.so -lc -lnsl -lm libgst/.libs/libgst.a(save.o): In function `_gst_load_from_file':/home/whitebearded1/src/smalltalk/libgst/save.c:493: undefined reference to `_gst_primitives_md5' libgst/.libs/libgst.a(save.o): In function `save_file_version':/home/whitebearded1/src/smalltalk/libgst/save.c:427: undefined reference to `_gst_primitives_md5' :/home/whitebearded1/src/smalltalk/libgst/save.c:427: undefined reference to `_gst_primitives_md5' :/home/whitebearded1/src/smalltalk/libgst/save.c:427: undefined reference to `_gst_primitives_md5' :/home/whitebearded1/src/smalltalk/libgst/save.c:427: undefined reference to `_gst_primitives_md5' collect2: ld returned 1 exit status make[2]: *** [gst] Error 1 make[2]: Leaving directory `/home/whitebearded1/src/smalltalk' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/whitebearded1/src/smalltalk' make: *** [all] Error 2 Brad Watson ----- Original Message ---- From: Paolo Bonzini <paolo.bonzini@xxxxxxxxxxx> To: Brad Watson <whitebearded1@xxxxxxxxx> Cc: help-smalltalk@xxxxxxx Sent: Friday, December 29, 2006 2:09:44 AM Subject: Re: [Help-smalltalk] failed build attempt Brad Watson wrote: > I pulled the lastest cvs updated, attempted to re-build, > and encountered the following: I updated CVS to match my tree. You may try again now. Paolo __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
Date: December 29, 2006
From: Paolo Bonzini <paolo.bonzini@xxxxxxxxxxx>
In-reply-to:
<20061228171508.94552.qmail@xxxxxxxxxxxxxxxxxxxxxxx>
References:
<20061228171508.94552.qmail@xxxxxxxxxxxxxxxxxxxxxxx>
Brad Watson wrote:
I pulled the lastest cvs updated, attempted to re-build, and encountered the following:
I updated CVS to match my tree. You may try again now. Paolo
Date: December 29, 2006
From: Paolo Bonzini <paolo.bonzini@xxxxxxxxxxx>
Anyway, now hello world is 4-5 times faster than when I started. Paolo
* looking for bonzini@xxxxxxxxxxxxxx/smalltalk--devo--2.2--patch-227 to compare
with
* comparing to bonzini@xxxxxxxxxxxxxx/smalltalk--devo--2.2--patch-227
M libgst/ChangeLog
M libgst/genpr-parse.c
M libgst/genpr-parse.h
M libgst/interp.h
M libgst/dict.c
M libgst/save.c
M libgst/dict.h
M libgst/genpr-parse.y
* modified files
--- orig/libgst/ChangeLog
+++ mod/libgst/ChangeLog
@@ -1,5 +1,18 @@
2006-12-28 Paolo Bonzini <bonzini@xxxxxxx>
+ * libgst/dict.c: Change _gst_init_dictionary_on_image_load to be
+ whether the primitive table's checksum is ok. If it is, just copy
+ the default primitive table just like in _gst_init_dictionary.
+ * libgst/dict.h: Adjust for above change.
+ * libgst/genpr-parse.y: Compute MD5 of DEF_FIL as checksum and
+ print it.
+ * libgst/interp.h: Declare _gst_primitives_md5.
+ * libgst/save.c: Save its contents, and compare it to pass the new flag
+ to _gst_init_dictionary_on_image_load. Move checks from load_snapshot
+ to load_file_version.
+
+2006-12-28 Paolo Bonzini <bonzini@xxxxxxx>
+
* libgst/gstpriv.h: Remove F_FREE.
* libgst/oop.c: Remove loops setting flags to F_FREE. Set flags to 0
instead of F_FREE elsewhere.
--- orig/libgst/dict.c
+++ mod/libgst/dict.c
@@ -1223,7 +1223,7 @@ create_class (const class_definition *ci
mst_Boolean
-_gst_init_dictionary_on_image_load (size_t numOOPs)
+_gst_init_dictionary_on_image_load (mst_Boolean prim_table_matches)
{
const class_definition *ci;
@@ -1259,7 +1259,12 @@ _gst_init_dictionary_on_image_load (size
/* Important: this is called *after* _gst_init_symbols
fills in _gst_vm_primitives_symbol! */
- prepare_primitive_numbers_table ();
+ if (prim_table_matches)
+ memcpy (_gst_primitive_table, _gst_default_primitive_table,
+ sizeof (_gst_primitive_table));
+ else
+ prepare_primitive_numbers_table ();
+
init_runtime_objects ();
return (true);
}
--- orig/libgst/dict.h
+++ mod/libgst/dict.h
@@ -603,10 +603,10 @@ extern void _gst_set_oop_bytes (OOP byte
extern void _gst_free_cobject (OOP cObjOOP)
ATTRIBUTE_HIDDEN;
-/* Loads the contents of the global variable from the Smalltalk
- dictionary after NUMOOPS objects have been loaded from an
- image. */
-extern mst_Boolean _gst_init_dictionary_on_image_load (size_t numOOPs)
+/* Loads the contents of the global variables from the Smalltalk dictionary
+ after an image has been restored. PRIM_TABLE_MATCHES if true if the
+ table of primitives is already set up correctly. */
+extern mst_Boolean _gst_init_dictionary_on_image_load (mst_Boolean
prim_table_matches)
ATTRIBUTE_HIDDEN;
/* Transforms a primitive name into a primitive index, looking up
--- orig/libgst/genpr-parse.c
+++ mod/libgst/genpr-parse.c
@@ -89,6 +89,7 @@
#line 52 "genpr-parse.y"
#include "genprims.h"
+#include "md5.h"
/* This program finds declarations of the form:
@@ -169,14 +170,14 @@ static string_list *current_ids;
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 117 "genpr-parse.y"
+#line 118 "genpr-parse.y"
{
Filament *fil;
char *text;
int id;
}
/* Line 193 of yacc.c. */
-#line 180 "../../libgst/genpr-parse.c"
+#line 181 "../../libgst/genpr-parse.c"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
@@ -189,7 +190,7 @@ typedef union YYSTYPE
/* Line 216 of yacc.c. */
-#line 193 "../../libgst/genpr-parse.c"
+#line 194 "../../libgst/genpr-parse.c"
#ifdef short
# undef short
@@ -479,9 +480,9 @@ static const yytype_int8 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] =
{
- 0, 140, 140, 139, 148, 154, 153, 166, 171, 177,
- 182, 188, 196, 201, 210, 213, 220, 219, 232, 236,
- 241, 240
+ 0, 141, 141, 140, 149, 155, 154, 167, 172, 178,
+ 183, 189, 197, 202, 211, 214, 221, 220, 233, 237,
+ 242, 241
};
#endif
@@ -1402,27 +1403,27 @@ yyreduce:
switch (yyn)
{
case 2:
-#line 140 "genpr-parse.y"
+#line 141 "genpr-parse.y"
{
filprintf (stmt_fil, "#line %d \"prims.def\"\n{", yylineno);
}
break;
case 3:
-#line 144 "genpr-parse.y"
+#line 145 "genpr-parse.y"
{
free_data ();
}
break;
case 4:
-#line 148 "genpr-parse.y"
+#line 149 "genpr-parse.y"
{
}
break;
case 5:
-#line 154 "genpr-parse.y"
+#line 155 "genpr-parse.y"
{
current_id = 0;
current_func_name = strdup ((yyvsp[(2) - (2)].text));
@@ -1432,13 +1433,13 @@ yyreduce:
break;
case 6:
-#line 161 "genpr-parse.y"
+#line 162 "genpr-parse.y"
{
}
break;
case 7:
-#line 167 "genpr-parse.y"
+#line 168 "genpr-parse.y"
{
gen_prim_id (current_func_name, (yyvsp[(1) - (2)].id), (yyvsp[(2) -
(2)].text));
free ((yyvsp[(2) - (2)].text));
@@ -1446,27 +1447,27 @@ yyreduce:
break;
case 8:
-#line 172 "genpr-parse.y"
+#line 173 "genpr-parse.y"
{
}
break;
case 9:
-#line 178 "genpr-parse.y"
+#line 179 "genpr-parse.y"
{
(yyval.id) = strtoul ((yyvsp[(2) - (2)].text), NULL, 10);
}
break;
case 10:
-#line 182 "genpr-parse.y"
+#line 183 "genpr-parse.y"
{
(yyval.id) = current_id--;
}
break;
case 11:
-#line 189 "genpr-parse.y"
+#line 190 "genpr-parse.y"
{
(yyval.text) = fildelete ((yyvsp[(2) - (3)].fil));
strupr ((yyval.text));
@@ -1474,7 +1475,7 @@ yyreduce:
break;
case 12:
-#line 197 "genpr-parse.y"
+#line 198 "genpr-parse.y"
{
(yyval.fil) = filnew ("PRIM_", 5);
filcat ((yyval.fil), (yyvsp[(1) - (1)].text));
@@ -1482,7 +1483,7 @@ yyreduce:
break;
case 13:
-#line 202 "genpr-parse.y"
+#line 203 "genpr-parse.y"
{
(yyval.fil) = (yyvsp[(1) - (3)].fil);
filcat ((yyval.fil), " | PRIM_");
@@ -1491,26 +1492,26 @@ yyreduce:
break;
case 14:
-#line 211 "genpr-parse.y"
+#line 212 "genpr-parse.y"
{
}
break;
case 15:
-#line 214 "genpr-parse.y"
+#line 215 "genpr-parse.y"
{
}
break;
case 16:
-#line 220 "genpr-parse.y"
+#line 221 "genpr-parse.y"
{
(yyval.text) = strdup((yyvsp[(2) - (2)].text));
}
break;
case 17:
-#line 224 "genpr-parse.y"
+#line 225 "genpr-parse.y"
{
gen_prim_id ((yyvsp[(3) - (5)].text), (yyvsp[(4) - (5)].id),
(yyvsp[(5) - (5)].text));
free ((yyvsp[(3) - (5)].text));
@@ -1519,14 +1520,14 @@ yyreduce:
break;
case 18:
-#line 233 "genpr-parse.y"
+#line 234 "genpr-parse.y"
{
filprintf (stmt_fil, "%d", (yyvsp[(2) - (2)].id));
}
break;
case 20:
-#line 241 "genpr-parse.y"
+#line 242 "genpr-parse.y"
{
(yyval.id) = lookup_prim_id ((yyvsp[(3) - (3)].text));
if ((yyval.id) == NOT_FOUND)
@@ -1535,7 +1536,7 @@ yyreduce:
break;
case 21:
-#line 247 "genpr-parse.y"
+#line 248 "genpr-parse.y"
{
(yyval.id) = (yyvsp[(4) - (5)].id);
literal_fil = stmt_fil;
@@ -1544,7 +1545,7 @@ yyreduce:
/* Line 1267 of yacc.c. */
-#line 1548 "../../libgst/genpr-parse.c"
+#line 1549 "../../libgst/genpr-parse.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1758,7 +1759,7 @@ yyreturn:
}
-#line 253 "genpr-parse.y"
+#line 254 "genpr-parse.y"
void
@@ -1865,12 +1866,16 @@ void
output()
{
char *proto, *stmt, *def;
+ unsigned int md5[16 / sizeof (int)];
+
gen_proto ("VMpr_HOLE");
proto = fildelete (proto_fil);
stmt = fildelete (stmt_fil);
def = fildelete (def_fil);
+ md5_buffer (def, strlen (def), md5);
+
printf ("%s\n"
"%s\n"
"intptr_t\n"
@@ -1884,6 +1889,8 @@ output()
" PRIM_FAILED;\n"
"}\n"
"\n"
+ "int _gst_primitives_md5[4] = { 0x%x, 0x%x, 0x%x, 0x%x };\n"
+ "\n"
"void\n"
"_gst_init_primitives()\n"
"{\n"
@@ -1898,7 +1905,10 @@ output()
" _gst_default_primitive_table[i].func = VMpr_HOLE;\n"
" }\n"
"}\n"
- "\n", proto, stmt, def, prim_no + 1);
+ "\n",
+ proto, stmt,
+ md5[0], md5[1], md5[2], md5[3],
+ def, prim_no + 1);
free (proto);
free (stmt);
--- orig/libgst/genpr-parse.h
+++ mod/libgst/genpr-parse.h
@@ -60,7 +60,7 @@
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
-#line 117 "genpr-parse.y"
+#line 118 "genpr-parse.y"
{
Filament *fil;
char *text;
--- orig/libgst/genpr-parse.y
+++ mod/libgst/genpr-parse.y
@@ -51,6 +51,7 @@
%{
#include "genprims.h"
+#include "md5.h"
/* This program finds declarations of the form:
@@ -356,12 +357,16 @@ void
output()
{
char *proto, *stmt, *def;
+ unsigned int md5[16 / sizeof (int)];
+
gen_proto ("VMpr_HOLE");
proto = fildelete (proto_fil);
stmt = fildelete (stmt_fil);
def = fildelete (def_fil);
+ md5_buffer (def, strlen (def), md5);
+
printf ("%s\n"
"%s\n"
"intptr_t\n"
@@ -375,6 +380,8 @@ output()
" PRIM_FAILED;\n"
"}\n"
"\n"
+ "int _gst_primitives_md5[4] = { 0x%x, 0x%x, 0x%x, 0x%x };\n"
+ "\n"
"void\n"
"_gst_init_primitives()\n"
"{\n"
@@ -389,7 +396,10 @@ output()
" _gst_default_primitive_table[i].func = VMpr_HOLE;\n"
" }\n"
"}\n"
- "\n", proto, stmt, def, prim_no + 1);
+ "\n",
+ proto, stmt,
+ md5[0], md5[1], md5[2], md5[3],
+ def, prim_no + 1);
free (proto);
free (stmt);
--- orig/libgst/interp.h
+++ mod/libgst/interp.h
@@ -542,6 +542,11 @@ prim_table_entry;
#define PRIM_RETURN_SMALL_INTEGER 0x0100 /* 31 or 63 bits */
#define PRIM_RETURN_SMALL_SMALLINTEGER 0x0300 /* 30 or 62 bits */
+/* The checksum of the table of primitive numbers. Right now it is an MD5,
+ computed from part of the C source code of prims.inl. We compare it when
+ loading an image, to avoid having to reload the primitive table. */
+extern int _gst_primitives_md5[4];
+
/* The table of functions that implement the primitives. */
extern prim_table_entry _gst_primitive_table[NUM_PRIMITIVES];
extern prim_table_entry _gst_default_primitive_table[NUM_PRIMITIVES];
--- orig/libgst/save.c
+++ mod/libgst/save.c
@@ -112,6 +112,7 @@ typedef struct save_file_header
size_t space_grow_rate;
size_t num_free_oops;
intptr_t ot_base;
+ int prim_table_md5[4]; /* checksum for the primitive table */
}
save_file_header;
@@ -212,8 +213,8 @@ static void save_file_version (int image
/* This function loads into HEADERP the header of the image file
without checking its validity.
This data is loaded from the IMAGEFD file descriptor. */
-static void load_file_version (int imageFd,
- save_file_header * headerp);
+static mst_Boolean load_file_version (int imageFd,
+ save_file_header * headerp);
/* This function walks the OOP table and converts all the relative
addresses for the instance variables to absolute ones. */
@@ -423,6 +424,8 @@ save_file_version (int imageFd, struct s
headerp->grow_threshold_percent = _gst_mem.grow_threshold_percent;
headerp->space_grow_rate = _gst_mem.space_grow_rate;
headerp->ot_base = (intptr_t) _gst_mem.ot_base;
+ memcpy (&headerp->prim_table_md5, _gst_primitives_md5, sizeof
(_gst_primitives_md5));
+
buffer_write (imageFd, headerp, sizeof (save_file_header));
}
@@ -451,34 +454,11 @@ mst_Boolean
load_snapshot (int imageFd)
{
save_file_header header;
+ int prim_table_matches;
buffer_read_init (imageFd, READ_BUFFER_SIZE);
- load_file_version (imageFd, &header);
- if (strcmp (header.signature, SIGNATURE))
- return (false);
-
- /* different sizeof(PTR) not supported */
- if (FLAG_CHANGED (header.flags, SLOT_SIZE_FLAG))
- return (false);
-
- if UNCOMMON ((wrong_endianness =
- FLAG_CHANGED (header.flags, ENDIANNESS_FLAG)))
- {
- header.oopTableSize = BYTE_INVERT (header.oopTableSize);
- header.edenSpaceSize = BYTE_INVERT (header.edenSpaceSize);
- header.survSpaceSize = BYTE_INVERT (header.survSpaceSize);
- header.oldSpaceSize = BYTE_INVERT (header.oldSpaceSize);
- header.big_object_threshold = BYTE_INVERT (header.big_object_threshold);
- header.grow_threshold_percent = BYTE_INVERT
(header.grow_threshold_percent);
- header.space_grow_rate = BYTE_INVERT (header.space_grow_rate);
- header.version = BYTE_INVERT (header.version);
- header.num_free_oops = BYTE_INVERT (header.num_free_oops);
- header.ot_base = BYTE_INVERT (header.ot_base);
- }
-
- /* check for version mismatch; if so this image file is invalid */
- if (header.version > VERSION_REQUIRED)
- return (false);
+ if (!load_file_version (imageFd, &header))
+ return false;
#ifdef SNAPSHOT_TRACE
printf ("After loading header: %lld\n", file_pos + buf_pos);
@@ -510,7 +490,9 @@ load_snapshot (int imageFd)
if (ot_delta)
restore_all_pointer_slots ();
- if (_gst_init_dictionary_on_image_load (num_used_oops))
+ prim_table_matches = !memcmp (header.prim_table_md5, _gst_primitives_md5,
+ sizeof (_gst_primitives_md5));
+ if (_gst_init_dictionary_on_image_load (prim_table_matches))
{
#ifdef SNAPSHOT_TRACE
_gst_dump_oop_table ();
@@ -521,19 +503,47 @@ load_snapshot (int imageFd)
return (false);
}
-void
+mst_Boolean
load_file_version (int imageFd,
save_file_header * headerp)
{
buffer_read (imageFd, headerp, sizeof (save_file_header));
+ if (strcmp (headerp->signature, SIGNATURE))
+ return (false);
+
+ /* different sizeof(PTR) not supported */
+ if (FLAG_CHANGED (headerp->flags, SLOT_SIZE_FLAG))
+ return (false);
+
+ if UNCOMMON ((wrong_endianness =
+ FLAG_CHANGED (headerp->flags, ENDIANNESS_FLAG)))
+ {
+ headerp->oopTableSize = BYTE_INVERT (headerp->oopTableSize);
+ headerp->edenSpaceSize = BYTE_INVERT (headerp->edenSpaceSize);
+ headerp->survSpaceSize = BYTE_INVERT (headerp->survSpaceSize);
+ headerp->oldSpaceSize = BYTE_INVERT (headerp->oldSpaceSize);
+ headerp->big_object_threshold = BYTE_INVERT
(headerp->big_object_threshold);
+ headerp->grow_threshold_percent = BYTE_INVERT
(headerp->grow_threshold_percent);
+ headerp->space_grow_rate = BYTE_INVERT (headerp->space_grow_rate);
+ headerp->version = BYTE_INVERT (headerp->version);
+ headerp->num_free_oops = BYTE_INVERT (headerp->num_free_oops);
+ headerp->ot_base = BYTE_INVERT (headerp->ot_base);
+ headerp->prim_table_md5[0] = BYTE_INVERT (headerp->prim_table_md5[0]);
+ headerp->prim_table_md5[1] = BYTE_INVERT (headerp->prim_table_md5[1]);
+ headerp->prim_table_md5[2] = BYTE_INVERT (headerp->prim_table_md5[2]);
+ headerp->prim_table_md5[3] = BYTE_INVERT (headerp->prim_table_md5[3]);
+ }
+
+ /* check for version mismatch; if so this image file is invalid */
+ if (headerp->version > VERSION_REQUIRED)
+ return (false);
+
+ return (true);
}
void
load_oop_table (int imageFd)
{
- OOP oop;
- int i;
-
/* Load in the valid OOP slots from previous dump. The others are already
initialized to free (0). */
buffer_read (imageFd, _gst_mem.ot, sizeof (struct oop_s) * num_used_oops);
_______________________________________________ help-smalltalk mailing list help-smalltalk@xxxxxxx http://lists.gnu.org/mailman/listinfo/help-smalltalk
Date: December 29, 2006
From: Paolo Bonzini <paolo.bonzini@xxxxxxxxxxx>
In-reply-to:
<1167296203.1657.9.camel@xxxxxxxxxxxxxxxxxx>
References:
<1167296203.1657.9.camel@xxxxxxxxxxxxxxxxxx>
Stephen Compall wrote:
Have a look:
That's a bug. The attached patch should do the job, but I have to test it a bit more before committing, since I took the occasion to do some simple refactoring.
Paolo
2006-12-29 Paolo Bonzini <bonzini@xxxxxxx>
* compiler/STCompLit.st: Don't use "nil" slots from VMSpecialMethods.
* compiler/STCompiler.st: Remove dupReceiver. Adjust for above change.
Compile receiver in compileTimesRepeat: and compileLoop:, test for
receiver being a block in compileWhileLoop:. Extract part of
acceptMessageNode: to compileMessage:. Compile receiver in
acceptCascadeNode: and call compileMessage: to avoid compiling the
receiver of a cascaded message repeatedly (reported by Stephen Compall).
--- orig/compiler/STCompLit.st
+++ mod/compiler/STCompLit.st
@@ -88,10 +88,10 @@ VMOtherConstants at: #VMSpecialIdentifie
yourself).
VMOtherConstants at: #VMSpecialMethods put: ((IdentityDictionary new: 32)
- at: #whileTrue put: nil ;
- at: #whileFalse put: nil ;
- at: #whileTrue: put: nil ;
- at: #whileFalse: put: nil ;
+ at: #whileTrue put: #compileWhileLoop: ;
+ at: #whileFalse put: #compileWhileLoop: ;
+ at: #whileTrue: put: #compileWhileLoop: ;
+ at: #whileFalse: put: #compileWhileLoop: ;
at: #timesRepeat: put: #compileTimesRepeat:;
at: #to:do: put: #compileLoop: ;
at: #to:by:do: put: #compileLoop: ;
--- orig/compiler/STCompiler.st
+++ mod/compiler/STCompiler.st
@@ -55,7 +55,7 @@ compile: methodDefNode for: aBehavior cl
! !
STFakeCompiler subclass: #STCompiler
- instanceVariableNames: 'node destClass symTable parser bytecodes depth
maxDepth isInsideBlock dupReceiver'
+ instanceVariableNames: 'node destClass symTable parser bytecodes depth
maxDepth isInsideBlock '
classVariableNames: 'OneNode TrueNode FalseNode NilNode SuperVariable
SelfVariable ThisContextVariable DoitToken'
poolDictionaries: ''
category: 'System-Compiler'
@@ -162,7 +162,6 @@ class: aBehavior parser: aParser
symTable := STSymbolTable new.
parser := aParser.
bytecodes := WriteStream on: (ByteArray new: 240).
- dupReceiver := false.
isInsideBlock := 0.
symTable declareEnvironment: aBehavior.
@@ -560,18 +559,18 @@ acceptCascadeNode: aNode
^aNode
].
- dupReceiver := true.
- first acceptVisitor: self.
+ first receiver acceptVisitor: self.
+ self depthIncr; compileByte: DupStackTop.
+ self compileMessage: first.
messages
from: 2 to: messages size - 1
do: [ :each |
self compileByte: PopStackTop; compileByte: DupStackTop.
- each acceptVisitor: self ].
+ self compileMessage: each ].
- self compileByte: PopStackTop.
- self depthDecr: 1.
- (messages at: messages size) acceptVisitor: self.
+ self depthDecr: 1; compileByte: PopStackTop.
+ self compileMessage: messages last.
! !
"--------------------------------------------------------------------"
@@ -619,29 +618,26 @@ acceptAssignmentNode: aNode
acceptMessageNode: aNode
"RBMessageNode contains a message send. Its instance variable are
a receiver, selector, and arguments."
- | dup specialSelector args litIndex |
+ | specialSelector |
- dup := dupReceiver. dupReceiver := false.
-
aNode receiver = SuperVariable ifTrue: [
self compileSendToSuper: aNode.
^true
].
- (VMSpecialMethods includesKey: aNode selector) ifTrue: [
- specialSelector := VMSpecialMethods at: aNode selector.
- (specialSelector isNil and: [aNode receiver isBlock and: [ dup not ]])
- ifTrue: [
- (self compileWhileLoop: aNode) ifTrue: [^false]
- ]
- ].
+ specialSelector := VMSpecialMethods at: aNode selector ifAbsent: [ nil ].
+ specialSelector isNil ifFalse: [
+ (self perform: specialSelector with: aNode) ifTrue: [ ^false ] ].
aNode receiver acceptVisitor: self.
- dup ifTrue: [ self depthIncr; compileByte: DupStackTop ].
- specialSelector isNil ifFalse: [
- (self perform: specialSelector with: aNode) ifTrue: [^false]
- ].
+ self compileMessage: aNode
+!
+compileMessage: aNode
+ "RBMessageNode contains a message send. Its instance variable are
+ a receiver, selector, and arguments. The receiver has already
+ been compiled."
+ | args litIndex |
aNode arguments do: [ :each | each acceptVisitor: self ].
VMSpecialSelectors at: aNode selector ifPresent: [ :idx |
@@ -662,6 +658,7 @@ compileWhileLoop: aNode
| whileBytecodes argBytecodes jumpOffsets |
+ aNode receiver isBlock ifFalse: [ ^false ].
(aNode receiver arguments isEmpty and: [
aNode receiver body temporaries isEmpty ]) ifFalse: [ ^false ].
@@ -731,6 +728,7 @@ compileSendToSuper: aNode
compileTimesRepeat: aNode
| block |
+ aNode receiver acceptVisitor: self.
block := aNode arguments first.
(block arguments isEmpty and: [
block body temporaries isEmpty ]) ifFalse: [ ^false ].
@@ -740,6 +738,7 @@ compileTimesRepeat: aNode
compileLoop: aNode
| stop step block |
+ aNode receiver acceptVisitor: self.
aNode arguments do: [ :each |
stop := step. "to:"
step := block. "by:"
@@ -757,6 +756,7 @@ compileLoop: aNode
compileBoolean: aNode
| bc1 ret1 bc2 selector |
+ aNode receiver acceptVisitor: self.
aNode arguments do: [ :each |
(each arguments isEmpty and: [
each body temporaries isEmpty ]) ifFalse: [ ^false ].
_______________________________________________ help-smalltalk mailing list help-smalltalk@xxxxxxx http://lists.gnu.org/mailman/listinfo/help-smalltalk
Date: December 28, 2006
From: Brad Watson <whitebearded1@xxxxxxxxx>
I pulled the lastest cvs updated, attempted to re-build, and encountered the
following:
.
.
.
echo timestamp > ./kernel/stamp-classes
SMALLTALK_KERNEL="`cd ./kernel; pwd`" \
SMALLTALK_IMAGE="`pwd`" \
./gst -iQ /dev/null
a Smalltalk string:1: undefined variable VMpr_Behavior_methodsFor referenced
/home/whitebearded1/src/smalltalk/kernel/Builtins.st:35: Aborted
/home/whitebearded1/src/smalltalk/kernel/Builtins.st:35: Error occurred while
not in byte code inter preter!!
[0xffffe420]
/lib/tls/i686/cmov/libc.so.6(abort+0xe9)[0x400b42b9]
./gst[0x8059868]
./gst[0x8082e03]
[0xffffe420]
./gst[0x805a084]
./gst[0x806dab9]
./gst[0x805a692]
./gst[0x805b16a]
./gst[0x805ad0a]
make[2]: *** [gst.im] Aborted
make[2]: Leaving directory `/home/whitebearded1/src/smalltalk'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/whitebearded1/src/smalltalk'
make: *** [all] Error 2
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Date: December 28, 2006
From: Krishna <v.krishnakumar@xxxxxxxxx>
In-reply-to:
<4593EDCC.2010401@xxxxxxxxxxx>
References:
<4593EDCC.2010401@xxxxxxxxxxx>
Hi Paolo, What is the overall improvement of patches 1/n..9/n? I'm stuck on the windoze land for the time being so could'nt try them out. Cheers, -Krishna -- I long to accomplish a great and noble task, but it is my chief duty to accomplish small tasks as if they were great and noble ! - Helen Keller
Date: December 28, 2006
From: Paolo Bonzini <paolo.bonzini@xxxxxxxxxxx>
Paolo
* looking for bonzini@xxxxxxxxxxxxxx/smalltalk--devo--2.2--patch-226 to compare
with
* comparing to bonzini@xxxxxxxxxxxxxx/smalltalk--devo--2.2--patch-226
M libgst/gstpriv.h
M libgst/oop.c
M libgst/oop.h
M libgst/print.c
M libgst/save.c
M libgst/oop.inl
* modified files
--- orig/libgst/gstpriv.h
+++ mod/libgst/gstpriv.h
@@ -258,9 +258,6 @@ enum {
saves and loads. */
F_RUNTIME = 0xFF8000U,
- /* Set if the OOP is currently unused. */
- F_FREE = 0x10U,
-
/* Set if the references to the instance variables of the object
are weak. */
F_WEAK = 0x20U,
--- orig/libgst/oop.c
+++ mod/libgst/oop.c
@@ -488,14 +488,16 @@ alloc_oop_table (size_t size)
_gst_mem.num_free_oops = size;
+#if 0
/* mark the OOPs as available */
PREFETCH_START (_gst_mem.ot, PREF_WRITE | PREF_NTA);
for (oop = _gst_mem.ot;
oop < &_gst_mem.ot[_gst_mem.ot_size]; oop++)
{
PREFETCH_LOOP (oop, PREF_WRITE | PREF_NTA);
- oop->flags = F_FREE;
+ oop->flags = 0;
}
+#endif
_gst_mem.first_allocated_oop = _gst_mem.ot;
_gst_mem.last_allocated_oop = _gst_mem.last_swept_oop = _gst_mem.ot - 1;
@@ -520,14 +522,16 @@ _gst_realloc_oop_table (size_t newSize)
return (false);
}
+#if 0
/* mark the new OOPs as available */
PREFETCH_START (&_gst_mem.ot[_gst_mem.ot_size], PREF_WRITE | PREF_NTA);
for (oop = &_gst_mem.ot[_gst_mem.ot_size];
oop < &_gst_mem.ot[newSize]; oop++)
{
PREFETCH_LOOP (oop, PREF_WRITE | PREF_NTA);
- oop->flags = F_FREE;
+ oop->flags = 0;
}
+#endif
_gst_mem.num_free_oops += newSize - _gst_mem.ot_size;
_gst_mem.ot_size = newSize;
@@ -1438,7 +1442,7 @@ _gst_sweep_oop (OOP oop)
_gst_mem_free (_gst_mem.old, oop->object);
}
- oop->flags = F_FREE;
+ oop->flags = 0;
}
void
@@ -1981,20 +1985,13 @@ _gst_copy_an_oop (OOP oop)
printf ("Invalid size for OOP %p (%p)\n", oop, obj);
abort ();
}
-#endif
- if UNCOMMON (oop->flags & F_FREE)
+ if UNCOMMON (oop->flags == 0)
{
printf ("Free OOP %p was referenced\n", oop);
- /* If we're lucky, we can print some information on it...
- if we're not, we segfault: not that bad given that
- we'll abort pretty soon! */
- oop->flags &= ~F_FREE;
- _gst_display_oop (oop);
abort ();
}
-#if defined (GC_DEBUGGING)
if UNCOMMON ((oop->flags & F_OLD) ||
IS_SURVIVOR_ADDR(obj, _gst_mem.active_half == &_gst_mem.surv[1]))
{
--- orig/libgst/oop.h
+++ mod/libgst/oop.h
@@ -220,7 +220,7 @@ struct memory_space
/* The OOP flag corresponding to the active survivor space */
int active_flag;
- /* The OOP flag corresponding to the inactive survivor space, plus F_FREE */
+ /* The OOP flag corresponding to the inactive survivor space. */
int live_flags;
/* These hold onto the object incubator's state */
--- orig/libgst/oop.inl
+++ mod/libgst/oop.inl
@@ -106,7 +106,7 @@ static inline OOP alloc_oop (PTR obj, in
((oop)->flags & F_REACHABLE)
#define IS_OOP_FREE(oop) \
- ((oop)->flags & F_FREE)
+ ((oop)->flags == 0)
/* Checks to see if INDEX (a long index into the OOP table, 1 based
due to being called from Smalltalk via a primitive) represents a
--- orig/libgst/print.c
+++ mod/libgst/print.c
@@ -320,7 +320,7 @@ _gst_classify_addr (void *addr)
void
_gst_display_oop_short (OOP oop)
{
- if (oop->flags & F_FREE)
+ if (IS_OOP_FREE (oop))
printf ("%-10p Free\n", oop);
else
{
@@ -351,7 +351,7 @@ _gst_display_oop (OOP oop)
return;
}
- if (oop->flags & F_FREE)
+ if (IS_OOP_FREE (oop))
printf ("%-10p Free\n", oop);
else
{
--- orig/libgst/save.c
+++ mod/libgst/save.c
@@ -355,7 +355,7 @@ make_oop_table_to_be_saved (struct save_
}
else
{
- myOOPTable[i].flags = F_FREE;
+ myOOPTable[i].flags = 0;
header->num_free_oops++;
}
}
@@ -535,7 +535,7 @@ load_oop_table (int imageFd)
int i;
/* Load in the valid OOP slots from previous dump. The others are already
- initialized to F_FREE. */
+ initialized to free (0). */
buffer_read (imageFd, _gst_mem.ot, sizeof (struct oop_s) * num_used_oops);
if UNCOMMON (wrong_endianness)
fixup_byte_order (_gst_mem.ot,
@@ -564,8 +564,7 @@ load_normal_oops (int imageFd)
PREFETCH_LOOP (oop, PREF_WRITE | PREF_NTA);
flags = oop->flags;
-
- if (flags & F_FREE)
+ if (IS_OOP_FREE (oop))
continue;
/* FIXME: a small amount of garbage is saved that is produced
@@ -598,7 +597,7 @@ load_normal_oops (int imageFd)
buffer_read (imageFd, object, size);
if UNCOMMON (wrong_endianness)
fixup_byte_order (object,
- (oop->flags & F_BYTE)
+ (flags & F_BYTE)
? OBJ_HEADER_SIZE_WORDS
: size / sizeof (PTR));
@@ -609,9 +608,7 @@ load_normal_oops (int imageFd)
abort ();
}
- /* Remove flags that are invalid after an image has been loaded. */
oop->object = object;
-
if (flags & F_WEAK)
_gst_make_oop_weak (oop);
}
_______________________________________________ help-smalltalk mailing list help-smalltalk@xxxxxxx http://lists.gnu.org/mailman/listinfo/help-smalltalk
Date: December 28, 2006
From: Paolo Bonzini <paolo.bonzini@xxxxxxxxxxx>
This brings several headaches:- each symbol is actually two objects, a Symbol and a SymLink. It's easier if we break symbol creation in two (creating Symbols as soon as possible, and the SymLinks only after we've created the system classes).
- there were two tables of symbols, one for the various _gst_*_symbol variables and one for the table of builtin selectors. It's easier if symbols only appear in one table.
- _gst_intern_string is called in a lot more places; in particular, to initialize the Smalltalk dictionary and to set up the table of primitives. It still accounts for ~10% of startup time, and we can get rid of it relatively easily. The Smalltalk dictionary's keys can be placed in _gst_*_symbol global variables, while the table of primitives should be checksummed in some way.
Paolo
006-12-28 Paolo Bonzini <bonzini@xxxxxxx>
* libgst/builtins.gperf: Remove _COLON from the enum for special
bytecodes.
* libgst/byte.def: Likewise.
* libgst/vm.def: Likewise.
* libgst/xlat.c: Likewise.
* libgst/comp.c: Remove the possibility to inline #perform:.
* libgst/byte.c: Turn _gst_builtin_selectors into an array of
structs (instead of pointers).
* libgst/opt.c: Likewise.
* libgst/sym.c: Likewise.
* libgst/vm.def: Use _gst_builtin_selectors instead of symbols
defined in sym.c (not slower with the change above).
* libgst/xlat.c: Only store the opcode in special_send_bytecodes and
use _gst_builtin_selectors for the other pieces of information.
* libgst/dict.c: Don't reload the _gst_*_class variables unless
necessary. Pass the class to identity_dictionary_new and adjust the
sole caller, _gst_valid_class_method_dictionary. Split the
creation of symbols in two parts (creating symbols, and populating
the symbol table with SymLink objects); call _gst_restore_symbols
when loading the image. Remove _gst_directed_message_new_args.
* libgst/interp.c: Remove commented out code to start call-ins through
Process>>#startExecution:.
* libgst/sym.c: Remove symbols for the special selectors. New
functions alloc_symbol_oop and alloc_symlink to support two-phase
creation of symbols in the image. Add _gst_smalltalk_namespace_symbol.
New functions intern_string_fast and _gst_restore_symbols to support
fast reloading of symbols when loading the image.
* libgst/sym.h: Adjust for changes to sym.c.
* libgst/genvm-parse.y: Add const qualifier to yyprint.
--- orig/libgst/builtins.gperf
+++ mod/libgst/builtins.gperf
@@ -47,13 +47,13 @@ struct builtin_selector { int offset; OO
*; NULL, 1, TIMES_SPECIAL
/; NULL, 1, DIVIDE_SPECIAL
\\; NULL, 1, REMAINDER_SPECIAL
-bitXor:; NULL, 1, BIT_XOR_COLON_SPECIAL
-bitShift:; NULL, 1, BIT_SHIFT_COLON_SPECIAL
+bitXor:; NULL, 1, BIT_XOR_SPECIAL
+bitShift:; NULL, 1, BIT_SHIFT_SPECIAL
//; NULL, 1, INTEGER_DIVIDE_SPECIAL
-bitAnd:; NULL, 1, BIT_AND_COLON_SPECIAL
-bitOr:; NULL, 1, BIT_OR_COLON_SPECIAL
-at:; NULL, 1, AT_COLON_SPECIAL
-at:put:; NULL, 2,
AT_COLON_PUT_COLON_SPECIAL
+bitAnd:; NULL, 1, BIT_AND_SPECIAL
+bitOr:; NULL, 1, BIT_OR_SPECIAL
+at:; NULL, 1, AT_SPECIAL
+at:put:; NULL, 2, AT_PUT_SPECIAL
size; NULL, 0, SIZE_SPECIAL
class; NULL, 0, CLASS_SPECIAL
isNil; NULL, 0, IS_NIL_SPECIAL
--- orig/libgst/builtins.inl
+++ mod/libgst/builtins.inl
@@ -1187,7 +1187,7 @@ static struct builtin_selector _gst_buil
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str650,
NULL, 1, NEW_COLON_SPECIAL},
{-1,NULL,-1,-1}, {-1,NULL,-1,-1}, {-1,NULL,-1,-1},
#line 55 "../../libgst/builtins.gperf"
- {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str654,
NULL, 1, AT_COLON_SPECIAL},
+ {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str654,
NULL, 1, AT_SPECIAL},
#line 265 "../../libgst/builtins.gperf"
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str655, NULL, 0,
231},
{-1,NULL,-1,-1}, {-1,NULL,-1,-1}, {-1,NULL,-1,-1},
@@ -1196,7 +1196,7 @@ static struct builtin_selector _gst_buil
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str660, NULL, 0,
129},
{-1,NULL,-1,-1}, {-1,NULL,-1,-1},
#line 51 "../../libgst/builtins.gperf"
- {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str663, NULL, 1,
BIT_SHIFT_COLON_SPECIAL},
+ {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str663, NULL, 1,
BIT_SHIFT_SPECIAL},
{-1,NULL,-1,-1},
#line 94 "../../libgst/builtins.gperf"
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str665,
NULL, 0, 60},
@@ -1259,7 +1259,7 @@ static struct builtin_selector _gst_buil
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str697, NULL, 0,
197},
{-1,NULL,-1,-1}, {-1,NULL,-1,-1},
#line 50 "../../libgst/builtins.gperf"
- {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str700,
NULL, 1, BIT_XOR_COLON_SPECIAL},
+ {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str700,
NULL, 1, BIT_XOR_SPECIAL},
#line 68 "../../libgst/builtins.gperf"
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str701, NULL, 1,
34},
{-1,NULL,-1,-1},
@@ -1355,7 +1355,7 @@ static struct builtin_selector _gst_buil
#line 85 "../../libgst/builtins.gperf"
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str768, NULL, 1,
51},
#line 53 "../../libgst/builtins.gperf"
- {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str769,
NULL, 1, BIT_AND_COLON_SPECIAL},
+ {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str769,
NULL, 1, BIT_AND_SPECIAL},
{-1,NULL,-1,-1}, {-1,NULL,-1,-1}, {-1,NULL,-1,-1},
#line 274 "../../libgst/builtins.gperf"
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str773, NULL, 2,
240},
@@ -1416,7 +1416,7 @@ static struct builtin_selector _gst_buil
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str816, NULL, 0,
57},
{-1,NULL,-1,-1}, {-1,NULL,-1,-1},
#line 54 "../../libgst/builtins.gperf"
- {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str819,
NULL, 1, BIT_OR_COLON_SPECIAL},
+ {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str819,
NULL, 1, BIT_OR_SPECIAL},
{-1,NULL,-1,-1},
#line 287 "../../libgst/builtins.gperf"
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str821,
NULL, 1, 253},
@@ -1451,7 +1451,7 @@ static struct builtin_selector _gst_buil
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str852, NULL, 1,
255},
{-1,NULL,-1,-1},
#line 56 "../../libgst/builtins.gperf"
- {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str854,
NULL, 2, AT_COLON_PUT_COLON_SPECIAL},
+ {(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str854,
NULL, 2, AT_PUT_SPECIAL},
{-1,NULL,-1,-1},
#line 78 "../../libgst/builtins.gperf"
{(int)(long)&((struct _gst_builtin_selectors_names_t
*)0)->_gst_builtin_selectors_names_str856, NULL, 0,
44},
--- orig/libgst/byte.c
+++ mod/libgst/byte.c
@@ -369,12 +369,12 @@ _gst_print_bytecode_name (gst_uchar * bp
SEND_ARITH {
printf ("%s\tsend arithmetic message %O\n", prefix,
- _gst_builtin_selectors[n]->symbol);
+ _gst_builtin_selectors[n].symbol);
prefix = pref;
}
SEND_SPECIAL {
printf ("%s\tsend special message %O\n", prefix,
- _gst_builtin_selectors[n + 16]->symbol);
+ _gst_builtin_selectors[n + 16].symbol);
prefix = pref;
}
@@ -385,7 +385,7 @@ _gst_print_bytecode_name (gst_uchar * bp
SEND_IMMEDIATE {
printf ("%s\tsend special message %O%s\n", prefix,
- _gst_builtin_selectors[n]->symbol,
+ _gst_builtin_selectors[n].symbol,
super ? " to super" : "");
prefix = pref;
}
--- orig/libgst/byte.def
+++ mod/libgst/byte.def
@@ -165,13 +165,13 @@ INVALID (opcode, arg);
dispatch SEND_ARITH (10);
}
-/* BIT_XOR_COLON_SPECIAL(*) */
+/* BIT_XOR_SPECIAL(*) */
11 {
extract opcode (8), arg_lsb (8);
dispatch SEND_ARITH (11);
}
-/* BIT_SHIFT_COLON_SPECIAL(*) */
+/* BIT_SHIFT_SPECIAL(*) */
12 {
extract opcode (8), arg_lsb (8);
dispatch SEND_ARITH (12);
@@ -183,25 +183,25 @@ INVALID (opcode, arg);
dispatch SEND_ARITH (13);
}
-/* BIT_AND_COLON_SPECIAL(*) */
+/* BIT_AND_SPECIAL(*) */
14 {
extract opcode (8), arg_lsb (8);
dispatch SEND_ARITH (14);
}
-/* BIT_OR_COLON_SPECIAL(*) */
+/* BIT_OR_SPECIAL(*) */
15 {
extract opcode (8), arg_lsb (8);
dispatch SEND_ARITH (15);
}
-/* AT_COLON_SPECIAL(*) */
+/* AT_SPECIAL(*) */
16 {
extract opcode (8), arg_lsb (8);
dispatch SEND_SPECIAL (0);
}
-/* AT_COLON_PUT_COLON_SPECIAL(*) */
+/* AT_PUT_SPECIAL(*) */
17 {
extract opcode (8), arg_lsb (8);
dispatch SEND_SPECIAL (1);
@@ -701,7 +701,7 @@ INVALID (opcode, arg);
}
/* PUSH_INTEGER(*)
- AT_COLON_SPECIAL(0) */
+ AT_SPECIAL(0) */
91 {
extract opcode (8), arg_lsb (8);
dispatch PUSH_INTEGER (arg | arg_lsb);
@@ -726,7 +726,7 @@ INVALID (opcode, arg);
}
/* PUSH_TEMPORARY_VARIABLE(*)
- AT_COLON_SPECIAL(0) */
+ AT_SPECIAL(0) */
94 {
extract opcode (8), arg_lsb (8);
dispatch PUSH_TEMPORARY_VARIABLE (arg | arg_lsb);
@@ -1030,7 +1030,7 @@ INVALID (opcode, arg);
}
/* PUSH_TEMPORARY_VARIABLE(*)
- AT_COLON_PUT_COLON_SPECIAL(0) */
+ AT_PUT_SPECIAL(0) */
130 {
extract opcode (8), arg_lsb (8);
dispatch PUSH_TEMPORARY_VARIABLE (arg | arg_lsb);
@@ -1373,7 +1373,7 @@ INVALID (opcode, arg);
}
/* PUSH_INTEGER(*)
- BIT_AND_COLON_SPECIAL(0) */
+ BIT_AND_SPECIAL(0) */
169 {
extract opcode (8), arg_lsb (8);
dispatch PUSH_INTEGER (arg | arg_lsb);
@@ -1423,7 +1423,7 @@ INVALID (opcode, arg);
}
/* PUSH_LIT_CONSTANT(*)
- AT_COLON_PUT_COLON_SPECIAL(0) */
+ AT_PUT_SPECIAL(0) */
175 {
extract opcode (8), arg_lsb (8);
dispatch PUSH_LIT_CONSTANT (arg | arg_lsb);
@@ -1915,7 +1915,7 @@ INVALID (opcode, arg);
/* PUSH_LIT_CONSTANT(*)
PUSH_TEMPORARY_VARIABLE(0)
- AT_COLON_PUT_COLON_SPECIAL(0) */
+ AT_PUT_SPECIAL(0) */
230 {
extract opcode (8), arg_lsb (8);
dispatch PUSH_LIT_CONSTANT (arg | arg_lsb);
@@ -1924,7 +1924,7 @@ INVALID (opcode, arg);
}
/* PUSH_INTEGER(*)
- AT_COLON_PUT_COLON_SPECIAL(0) */
+ AT_PUT_SPECIAL(0) */
231 {
extract opcode (8), arg_lsb (8);
dispatch PUSH_INTEGER (arg | arg_lsb);
--- orig/libgst/byte.h
+++ mod/libgst/byte.h
@@ -67,14 +67,14 @@ enum {
TIMES_SPECIAL = 8,
DIVIDE_SPECIAL = 9,
REMAINDER_SPECIAL = 10,
- BIT_XOR_COLON_SPECIAL = 11,
- BIT_SHIFT_COLON_SPECIAL = 12,
+ BIT_XOR_SPECIAL = 11,
+ BIT_SHIFT_SPECIAL = 12,
INTEGER_DIVIDE_SPECIAL = 13,
- BIT_AND_COLON_SPECIAL = 14,
- BIT_OR_COLON_SPECIAL = 15,
+ BIT_AND_SPECIAL = 14,
+ BIT_OR_SPECIAL = 15,
- AT_COLON_SPECIAL = 16,
- AT_COLON_PUT_COLON_SPECIAL = 17,
+ AT_SPECIAL = 16,
+ AT_PUT_SPECIAL = 17,
SIZE_SPECIAL = 18,
CLASS_SPECIAL = 19,
IS_NIL_SPECIAL = 20,
--- orig/libgst/comp.c
+++ mod/libgst/comp.c
@@ -69,15 +69,6 @@
output for correctness. */
/* #define VERIFY_COMPILED_METHODS */
-/* Define this to inline #perform: with a constant selector. It is
- disabled because it removes some error checking. For example, it
- allows one to compile "self perform: #yourself with: 1", after
- which the compiler thinks that the stack is balanced, when in
- fact it is not (because #yourself is a SEND_IMMEDIATE selector);
- or even worse, "self perform: #this:that: with: 1", where the stack
- upon entry to #this:that: is confused beyond any recognition. */
-/* #define INLINE_PERFORM */
-
#define LITERAL_VEC_CHUNK_SIZE 32
@@ -185,13 +176,6 @@ static mst_Boolean compile_to_by_do (tre
tree_node by,
tree_node block);
-/* Special case compilation of #perform: and friends with a constant
- selector (in case of #perform:withArguments:, the arguments must be
- a constant array or an array constructor). This is done especially
- for the Java translator, but is always good, so why not? */
-static mst_Boolean compile_perform (OOP selectorOOP,
- tree_node expr);
-
/* Special case compilation of a #and: or #or: boolean operation; very
similar to compile_if_statement. EXPR is a node for the entire
keyword message send. Returns true if byte codes were emitted,
@@ -1407,15 +1391,6 @@ compile_keyword_expr (tree_node expr)
expr->v_expr.expression->v_list.next->v_list.next->v_list.value))
return;
}
- else if (selector == _gst_perform_symbol
- || selector == _gst_perform_with_symbol
- || selector == _gst_perform_with_with_symbol
- || selector == _gst_perform_with_with_with_symbol
- || selector == _gst_perform_with_arguments_symbol)
- {
- if (compile_perform (selector, expr))
- return;
- }
numArgs = list_length (expr->v_expr.expression);
@@ -1423,46 +1398,6 @@ compile_keyword_expr (tree_node expr)
compile_send (expr, selector, numArgs);
}
-mst_Boolean
-compile_perform (OOP selectorOOP,
- tree_node expr)
-{
-#ifdef INLINE_PERFORM
- tree_node selector = expr->v_expr.expression->v_list.value;
- tree_node args = expr->v_expr.expression->v_list.next;
- int i;
-
- /* We inline only if the selector is a symbol... */
- if (selector->nodeType != TREE_CONST_EXPR
- || selector->v_const.constType != CONST_OOP
- || OOP_CLASS (selector->v_const.val.oopVal) != _gst_symbol_class)
- return false;
-
- /* ... and in case of perform:withArguments:, if the list of arguments
- is a constant array or an array constructor. */
- if (selectorOOP == _gst_perform_with_arguments_symbol)
- {
- if (args->nodeType != TREE_ARRAY_CONSTRUCTOR
- || !(args->nodeType == TREE_CONST_EXPR
- && args->v_const.constType == CONST_ARRAY))
- return false;
-
- /* dive into the list of members of the array. */
- args = args->v_const.val.aVal;
- }
-
- /* compile the values now */
- for (i = 0; args; i++, args = args->v_list.next)
- compile_statement (args->v_list.value);
-
- /* and send the selector */
- compile_send (expr, selector->v_const.val.oopVal, i);
-
- return true;
-#else
- return false;
-#endif
-}
void
compile_send (tree_node expr,
--- orig/libgst/dict.c
+++ mod/libgst/dict.c
@@ -64,7 +64,8 @@ typedef struct class_definition
OOP *classVar;
OOP *superClassPtr;
intptr_t instanceSpec;
- char numFixedFields;
+ mst_Boolean reloadAddress;
+ int numFixedFields;
const char *name;
const char *instVarNames;
const char *classVarNames;
@@ -191,8 +192,10 @@ static ssize_t identity_dictionary_find_
static size_t identity_dictionary_find_key_or_nil (OOP identityDictionaryOOP,
OOP keyOOP);
-/* Create a new instance of IdentityDictionary and answer it. */
-static OOP identity_dictionary_new (int size);
+/* Create a new instance of CLASSOOP (an IdentityDictionary subclass)
+ and answer it. */
+static OOP identity_dictionary_new (OOP classOOP,
+ int size);
/* Create a new instance of Namespace with the given SIZE, NAME and
superspace (SUPERSPACEOOP). */
@@ -283,11 +286,11 @@ static const char *feature_strings[] = {
static const class_definition class_info[] = {
{&_gst_object_class, &_gst_nil_oop,
- ISP_FIXED, 0,
+ ISP_FIXED, true, 0,
"Object", NULL, "Dependencies FinalizableObjects", "VMPrimitives" },
{&_gst_object_memory_class, &_gst_object_class,
- ISP_FIXED, 34,
+ ISP_FIXED, true, 34,
"ObjectMemory", "bytesPerOOP bytesPerOTE "
"edenSize survSpaceSize oldSpaceSize fixedSpaceSize "
"edenUsedBytes survSpaceUsedBytes oldSpaceUsedBytes "
@@ -301,404 +304,396 @@ static const class_definition class_info
"allocFailures allocMatches allocSplits allocProbes", NULL, NULL },
{&_gst_message_class, &_gst_object_class,
- ISP_FIXED, 2,
+ ISP_FIXED, true, 2,
"Message", "selector args", NULL, NULL },
{&_gst_directed_message_class, &_gst_message_class,
- ISP_FIXED, 1,
+ ISP_FIXED, false, 1,
"DirectedMessage", "receiver", NULL, NULL },
{&_gst_magnitude_class, &_gst_object_class,
- ISP_FIXED, 0,
+ ISP_FIXED, false, 0,
"Magnitude", NULL, NULL, NULL },
{&_gst_char_class, &_gst_magnitude_class,
- ISP_FIXED, 1,
+ ISP_FIXED, true, 1,
"Character", "codePoint", "Table UpperTable LowerTable", NULL },
{&_gst_unicode_character_class, &_gst_char_class,
- ISP_FIXED, 0,
+ ISP_FIXED, true, 0,
"UnicodeCharacter", NULL, NULL, NULL },
{&_gst_time_class, &_gst_magnitude_class,
- ISP_FIXED, 1,
+ ISP_FIXED, false, 1,
"Time", "seconds",
"SecondClockAdjustment ClockOnStartup", NULL },
{&_gst_date_class, &_gst_magnitude_class,
- ISP_FIXED, 4,
+ ISP_FIXED, false, 4,
"Date", "days day month year",
"DayNameDict MonthNameDict", NULL },
{&_gst_number_class, &_gst_magnitude_class,
- ISP_FIXED, 0,
+ ISP_FIXED, false, 0,
"Number", NULL, NULL, NULL },
{&_gst_float_class, &_gst_number_class,
- ISP_UCHAR, 0,
+ ISP_UCHAR, true, 0,
"Float", NULL, NULL, "CSymbols" },
{&_gst_floatd_class, &_gst_float_class,
- ISP_UCHAR, 0,
+ ISP_UCHAR, true, 0,
"FloatD", NULL, NULL, "CSymbols" },
{&_gst_floate_class, &_gst_float_class,
- ISP_UCHAR, 0,
+ ISP_UCHAR, true, 0,
"FloatE", NULL, NULL, "CSymbols" },
{&_gst_floatq_class, &_gst_float_class,
- ISP_UCHAR, 0,
+ ISP_UCHAR, true, 0,
"FloatQ", NULL, NULL, "CSymbols" },
{&_gst_fraction_class, &_gst_number_class,
- ISP_FIXED, 2,
+ ISP_FIXED, false, 2,
"Fraction", "numerator denominator", "Zero One", NULL },
{&_gst_integer_class, &_gst_number_class,
- ISP_FIXED, 0,
+ ISP_FIXED, true, 0,
"Integer", NULL, NULL, "CSymbols" },
{&_gst_small_integer_class, &_gst_integer_class,
- ISP_FIXED, 0,
+ ISP_FIXED, true, 0,
"SmallInteger", NULL, NULL, NULL },
{&_gst_large_integer_class, &_gst_integer_class, /* these four
classes
added by */
- ISP_UCHAR, 0, /* pb Sep 10 18:06:49 1998 */
+ ISP_UCHAR, true, 0, /* pb Sep 10 18:06:49 1998 */
"LargeInteger",