To gain ~10% more (of course, 10% now being much less than 10% when I
started!) we can avoid doing hash table walks to find symbols at image load time. Instead, we group all symbols together at the beginning of the OOP table. 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 <[hidden email]> * 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", NULL, "Zero One ZeroBytes OneBytes LeadingZeros TrailingZeros", NULL }, {&_gst_large_positive_integer_class, &_gst_large_integer_class, - ISP_UCHAR, 0, + ISP_UCHAR, true, 0, "LargePositiveInteger", NULL, NULL, NULL }, {&_gst_large_zero_integer_class, &_gst_large_positive_integer_class, - ISP_UCHAR, 0, + ISP_UCHAR, true, 0, "LargeZeroInteger", NULL, NULL, NULL }, {&_gst_large_negative_integer_class, &_gst_large_integer_class, - ISP_UCHAR, 0, + ISP_UCHAR, true, 0, "LargeNegativeInteger", NULL, NULL, NULL }, {&_gst_lookup_key_class, &_gst_magnitude_class, - ISP_FIXED, 1, + ISP_FIXED, false, 1, "LookupKey", "key", NULL, NULL }, {&_gst_association_class, &_gst_lookup_key_class, - ISP_FIXED, 1, + ISP_FIXED, true, 1, "Association", "value", NULL, NULL }, {&_gst_homed_association_class, &_gst_association_class, - ISP_FIXED, 1, + ISP_FIXED, false, 1, "HomedAssociation", "environment", NULL, NULL }, {&_gst_variable_binding_class, &_gst_homed_association_class, - ISP_FIXED, 0, + ISP_FIXED, true, 0, "VariableBinding", NULL, NULL, NULL }, {&_gst_link_class, &_gst_object_class, - ISP_FIXED, 1, + ISP_FIXED, false, 1, "Link", "nextLink", NULL, NULL }, {&_gst_process_class, &_gst_link_class, - ISP_FIXED, 7, + ISP_FIXED, true, 7, "Process", "suspendedContext priority myList name unwindPoints interrupts interruptLock", NULL, NULL }, {&_gst_callin_process_class, &_gst_process_class, - ISP_FIXED, 1, + ISP_FIXED, true, 1, "CallinProcess", "returnedValue", NULL, NULL }, {&_gst_sym_link_class, &_gst_link_class, - ISP_FIXED, 1, + ISP_FIXED, true, 1, "SymLink", "symbol", NULL, NULL }, {&_gst_collection_class, &_gst_object_class, - ISP_FIXED, 0, + ISP_FIXED, false, 0, "Collection", NULL, NULL, NULL }, {&_gst_sequenceable_collection_class, &_gst_collection_class, - ISP_FIXED, 0, + ISP_FIXED, false, 0, "SequenceableCollection", NULL, NULL, NULL }, {&_gst_linked_list_class, &_gst_sequenceable_collection_class, - ISP_FIXED, 2, + ISP_FIXED, false, 2, "LinkedList", "firstLink lastLink", NULL, NULL }, {&_gst_semaphore_class, &_gst_linked_list_class, - ISP_FIXED, 2, + ISP_FIXED, true, 2, "Semaphore", "signals name", NULL, NULL }, {&_gst_arrayed_collection_class, &_gst_sequenceable_collection_class, - ISP_POINTER, 0, + ISP_POINTER, false, 0, "ArrayedCollection", NULL, NULL, NULL }, {&_gst_array_class, &_gst_arrayed_collection_class, - ISP_POINTER, 0, + ISP_POINTER, true, 0, "Array", NULL, NULL, NULL }, {&_gst_character_array_class, &_gst_arrayed_collection_class, - ISP_ULONG, 0, + ISP_ULONG, false, 0, "CharacterArray", NULL, NULL, NULL }, {&_gst_string_class, &_gst_character_array_class, - ISP_CHARACTER, 0, + ISP_CHARACTER, true, 0, "String", NULL, NULL, NULL }, {&_gst_unicode_string_class, &_gst_character_array_class, - ISP_UTF32, 0, + ISP_UTF32, true, 0, "UnicodeString", NULL, NULL, NULL }, {&_gst_symbol_class, &_gst_string_class, - ISP_CHARACTER, 0, + ISP_CHARACTER, true, 0, "Symbol", NULL, NULL, NULL }, {&_gst_byte_array_class, &_gst_arrayed_collection_class, - ISP_UCHAR, 0, + ISP_UCHAR, true, 0, "ByteArray", NULL, NULL, "CSymbols" }, {&_gst_compiled_code_class, &_gst_arrayed_collection_class, - ISP_UCHAR, 2, + ISP_UCHAR, false, 2, "CompiledCode", "literals header", NULL, NULL }, {&_gst_compiled_block_class, &_gst_compiled_code_class, - ISP_UCHAR, 1, + ISP_UCHAR, true, 1, "CompiledBlock", "method", NULL, NULL }, {&_gst_compiled_method_class, &_gst_compiled_code_class, - ISP_UCHAR, 1, + ISP_UCHAR, true, 1, "CompiledMethod", "descriptor ", NULL, NULL }, {&_gst_interval_class, &_gst_arrayed_collection_class, - ISP_FIXED, 3, + ISP_FIXED, true, 3, "Interval", "start stop step", NULL, NULL }, {&_gst_ordered_collection_class, &_gst_sequenceable_collection_class, - ISP_POINTER, 2, + ISP_POINTER, false, 2, "OrderedCollection", "firstIndex lastIndex", NULL, NULL }, {&_gst_sorted_collection_class, &_gst_ordered_collection_class, - ISP_POINTER, 3, + ISP_POINTER, false, 3, "SortedCollection", "lastOrdered sorted sortBlock", "DefaultSortBlock", NULL }, {&_gst_bag_class, &_gst_collection_class, - ISP_FIXED, 1, + ISP_FIXED, false, 1, "Bag", "contents", NULL, NULL }, {&_gst_mapped_collection_class, &_gst_collection_class, - ISP_FIXED, 2, + ISP_FIXED, false, 2, "MappedCollection", "domain map", NULL, NULL }, {&_gst_hashed_collection_class, &_gst_collection_class, - ISP_POINTER, 1, + ISP_POINTER, false, 1, "HashedCollection", "tally", NULL, NULL }, {&_gst_set_class, &_gst_hashed_collection_class, - ISP_POINTER, 0, + ISP_POINTER, false, 0, "Set", NULL, NULL, NULL }, {&_gst_identity_set_class, &_gst_set_class, - ISP_POINTER, 0, + ISP_POINTER, false, 0, "IdentitySet", NULL, NULL, NULL }, {&_gst_dictionary_class, &_gst_hashed_collection_class, - ISP_POINTER, 0, + ISP_POINTER, true, 0, "Dictionary", NULL, NULL, NULL }, {&_gst_lookup_table_class, &_gst_dictionary_class, - ISP_POINTER, 0, + ISP_POINTER, false, 0, "LookupTable", NULL, NULL, NULL }, {&_gst_identity_dictionary_class, &_gst_lookup_table_class, - ISP_POINTER, 0, + ISP_POINTER, false, 0, "IdentityDictionary", NULL, NULL, NULL }, {&_gst_method_dictionary_class, &_gst_lookup_table_class, - ISP_POINTER, 0, + ISP_POINTER, true, 0, "MethodDictionary", NULL, NULL, NULL }, /* These five MUST have the same structure as dictionary; they're used interchangeably within the C portion of the system */ {&_gst_binding_dictionary_class, &_gst_dictionary_class, - ISP_POINTER, 1, + ISP_POINTER, false, 1, "BindingDictionary", "environment", NULL, NULL }, {&_gst_abstract_namespace_class, &_gst_binding_dictionary_class, - ISP_POINTER, 2, + ISP_POINTER, true, 2, "AbstractNamespace", "name subspaces", NULL, NULL }, {&_gst_root_namespace_class, &_gst_abstract_namespace_class, - ISP_POINTER, 0, + ISP_POINTER, false, 0, "RootNamespace", NULL, NULL, NULL }, {&_gst_namespace_class, &_gst_abstract_namespace_class, - ISP_POINTER, 0, + ISP_POINTER, true, 0, "Namespace", NULL, "Current", NULL }, {&_gst_system_dictionary_class, &_gst_root_namespace_class, - ISP_POINTER, 0, + ISP_POINTER, false, 0, "SystemDictionary", NULL, NULL, NULL }, {&_gst_stream_class, &_gst_object_class, - ISP_FIXED, 0, + ISP_FIXED, false, 0, "Stream", NULL, NULL, NULL }, {&_gst_token_stream_class, &_gst_stream_class, - ISP_FIXED, 1, + ISP_FIXED, false, 1, "TokenStream", "charStream", NULL, NULL }, {&_gst_positionable_stream_class, &_gst_stream_class, - ISP_FIXED, 4, + ISP_FIXED, false, 4, "PositionableStream", "collection ptr endPtr access", NULL, NULL }, {&_gst_read_stream_class, &_gst_positionable_stream_class, - ISP_FIXED, 0, + ISP_FIXED, false, 0, "ReadStream", NULL, NULL, NULL }, {&_gst_write_stream_class, &_gst_positionable_stream_class, - ISP_FIXED, 0, + ISP_FIXED, false, 0, "WriteStream", NULL, NULL, NULL }, {&_gst_read_write_stream_class, &_gst_write_stream_class, - ISP_FIXED, 0, + ISP_FIXED, false, 0, "ReadWriteStream", NULL, NULL, NULL }, {&_gst_byte_stream_class, &_gst_read_write_stream_class, - ISP_FIXED, 0, + ISP_FIXED, false, 0, "ByteStream", NULL, NULL, NULL }, {&_gst_file_descriptor_class, &_gst_byte_stream_class, - ISP_FIXED, 5, + ISP_FIXED, true, 5, "FileDescriptor", "file name isPipe atEnd peek", NULL, NULL }, {&_gst_file_stream_class, &_gst_file_descriptor_class, - ISP_FIXED, 2, + ISP_FIXED, true, 2, "FileStream", "writePtr writeEnd", "Verbose Record Includes", NULL }, {&_gst_random_class, &_gst_stream_class, - ISP_FIXED, 1, + ISP_FIXED, false, 1, "Random", "seed", "Source", NULL }, {&_gst_undefined_object_class, &_gst_object_class, - ISP_FIXED, 0, + ISP_FIXED, true, 0, "UndefinedObject", NULL, NULL, NULL }, {&_gst_boolean_class, &_gst_object_class, - ISP_FIXED, 0, + ISP_FIXED, true, 0, "Boolean", NULL, NULL, NULL }, {&_gst_false_class, &_gst_boolean_class, - ISP_FIXED, 1, + ISP_FIXED, true, 1, "False", "truthValue", NULL, NULL }, {&_gst_true_class, &_gst_boolean_class, - ISP_FIXED, 1, + ISP_FIXED, true, 1, "True", "truthValue", NULL, NULL }, {&_gst_processor_scheduler_class, &_gst_object_class, - ISP_FIXED, 6, + ISP_FIXED, false, 6, "ProcessorScheduler", "processLists activeProcess idleTasks processTimeslice gcSemaphore gcArray", NULL, NULL }, {&_gst_delay_class, &_gst_object_class, - ISP_FIXED, 2, + ISP_FIXED, false, 2, "Delay", "resumptionTime isRelative", "Queue TimeoutSem MutexSem DelayProcess IdleProcess", NULL }, {&_gst_shared_queue_class, &_gst_object_class, - ISP_FIXED, 3, + ISP_FIXED, false, 3, "SharedQueue", "queueSem valueReady queue", NULL, NULL }, /* Change this, classDescription, or gst_class, and you must change the implementaion of new_metaclass some */ {&_gst_behavior_class, &_gst_object_class, - ISP_FIXED, 5, + ISP_FIXED, true, 5, "Behavior", "superClass subClasses methodDictionary instanceSpec instanceVariables", NULL, NULL }, {&_gst_class_description_class, &_gst_behavior_class, - ISP_FIXED, 0, + ISP_FIXED, true, 0, "ClassDescription", NULL, NULL, NULL }, {&_gst_class_class, &_gst_class_description_class, - ISP_FIXED, 8, + ISP_FIXED, true, 8, "Class", "name comment category environment classVariables sharedPools " "securityPolicy pragmaHandlers", NULL, NULL }, {&_gst_metaclass_class, &_gst_class_description_class, - ISP_FIXED, 1, + ISP_FIXED, true, 1, "Metaclass", "instanceClass", NULL, NULL }, {&_gst_context_part_class, &_gst_object_class, - ISP_POINTER, 6, + ISP_POINTER, true, 6, "ContextPart", "parent nativeIP ip sp receiver method ", "UnwindPoints", NULL }, {&_gst_method_context_class, &_gst_context_part_class, - ISP_POINTER, 1, + ISP_POINTER, true, 1, "MethodContext", "flags ", NULL, NULL }, {&_gst_block_context_class, &_gst_context_part_class, - ISP_POINTER, 1, + ISP_POINTER, true, 1, "BlockContext", "outerContext ", NULL, NULL }, {&_gst_block_closure_class, &_gst_object_class, - ISP_FIXED, 3, + ISP_FIXED, true, 3, "BlockClosure", "outerContext block receiver", NULL, NULL }, - -/*********************************************************************** - * - * End of Standard Smalltalk Class definitions. The definitions below are - * specific to GNU Smalltalk. - * - ***********************************************************************/ - {&_gst_permission_class, &_gst_object_class, - ISP_FIXED, 4, + ISP_FIXED, true, 4, "Permission", "name actions target positive", NULL, NULL }, {&_gst_security_policy_class, &_gst_object_class, - ISP_FIXED, 2, + ISP_FIXED, true, 2, "SecurityPolicy", "dictionary owner", NULL, NULL }, {&_gst_c_object_class, &_gst_object_class, - ISP_ULONG, 1, /* leave this this way */ + ISP_ULONG, true, 1, /* leave this this way */ "CObject", "type", NULL, "CSymbols" }, {&_gst_c_type_class, &_gst_object_class, - ISP_FIXED, 1, + ISP_FIXED, true, 1, "CType", "cObjectType", NULL, NULL }, {&_gst_c_func_descriptor_class, &_gst_object_class, - ISP_POINTER, 4, + ISP_POINTER, true, 4, "CFunctionDescriptor", "cFunction cFunctionName returnType numFixedArgs", NULL, NULL }, {&_gst_memory_class, &_gst_object_class, - ISP_FIXED, 0, + ISP_FIXED, false, 0, "Memory", NULL, NULL, NULL }, {&_gst_method_info_class, &_gst_object_class, - ISP_POINTER, 4, + ISP_POINTER, true, 4, "MethodInfo", "sourceCode category class selector", NULL, NULL }, {&_gst_file_segment_class, &_gst_object_class, - ISP_FIXED, 3, + ISP_FIXED, true, 3, "FileSegment", "file startPos size", NULL, NULL } /* Classes not defined here (like Point/Rectangle/RunArray) are @@ -749,7 +744,7 @@ init_proto_oops() smalltalkDictionary->objClass = _gst_system_dictionary_class; smalltalkDictionary->tally = FROM_INT(0); - smalltalkDictionary->name = _gst_intern_string ("Smalltalk"); + smalltalkDictionary->name = _gst_smalltalk_namespace_symbol; smalltalkDictionary->superspace = _gst_nil_oop; smalltalkDictionary->subspaces = _gst_nil_oop; nil_fill (smalltalkDictionary->assoc, @@ -776,9 +771,12 @@ _gst_init_dictionary (void) _gst_processor_oop = alloc_oop (NULL, _gst_mem.active_flag); _gst_symbol_table = alloc_oop (NULL, _gst_mem.active_flag); + _gst_init_symbols_pass1 (); + create_classes_pass1 (class_info, sizeof (class_info) / sizeof (class_info[0])); init_proto_oops(); + _gst_init_symbols_pass2 (); init_smalltalk_dictionary (); create_classes_pass2 (class_info, sizeof (class_info) / sizeof (class_info[0])); @@ -787,7 +785,6 @@ _gst_init_dictionary (void) _gst_string_new (_gst_kernel_file_path)); init_runtime_objects (); - _gst_tenure_all_survivors (); } @@ -998,8 +995,6 @@ init_smalltalk_dictionary (void) add_smalltalk ("Processor", _gst_processor_oop); add_smalltalk ("Features", featuresArrayOOP); - _gst_init_symbols (); - /* Add subspaces */ add_smalltalk ("CSymbols", namespace_new (32, "CSymbols", _gst_smalltalk_dictionary)); @@ -1240,27 +1235,27 @@ _gst_init_dictionary_on_image_load (size || IS_NIL (_gst_smalltalk_dictionary)) return (false); + _gst_restore_symbols (); + for (ci = class_info; ci < class_info + sizeof(class_info) / sizeof(class_definition); ci++) - { - *ci->classVar = dictionary_at (_gst_smalltalk_dictionary, - _gst_intern_string (ci->name)); - if UNCOMMON (IS_NIL (*ci->classVar)) - return (false); - } + if (ci->reloadAddress) + { + *ci->classVar = dictionary_at (_gst_smalltalk_dictionary, + _gst_intern_string (ci->name)); + if UNCOMMON (IS_NIL (*ci->classVar)) + return (false); + } _gst_current_namespace = - dictionary_at (_gst_class_variable_dictionary - (_gst_namespace_class), + dictionary_at (_gst_class_variable_dictionary (_gst_namespace_class), _gst_intern_string ("Current")); _gst_c_object_type_ctype = dictionary_at (_gst_smalltalk_dictionary, - _gst_intern_string - ("CObjectType")); + _gst_intern_string ("CObjectType")); _gst_init_builtin_objects_classes (); - _gst_init_symbols (); /* Important: this is called *after* _gst_init_symbols fills in _gst_vm_primitives_symbol! */ @@ -1342,9 +1337,8 @@ _gst_valid_class_method_dictionary (OOP { OOP identDict; gst_object obj; - identDict = identity_dictionary_new (32); + identDict = identity_dictionary_new (_gst_method_dictionary_class, 32); obj = OOP_TO_OBJ (identDict); - obj->objClass = _gst_method_dictionary_class; class = (gst_class) OOP_TO_OBJ (class_oop); class->methodDictionary = identDict; } @@ -1648,7 +1642,7 @@ identity_dictionary_find_key_or_nil (OOP } OOP -identity_dictionary_new (int size) +identity_dictionary_new (OOP classOOP, int size) { gst_identity_dictionary identityDictionary; OOP identityDictionaryOOP; @@ -1656,8 +1650,7 @@ identity_dictionary_new (int size) size = new_num_fields (size); identityDictionary = (gst_identity_dictionary) - instantiate_with (_gst_identity_dictionary_class, size * 2, - &identityDictionaryOOP); + instantiate_with (classOOP, size * 2, &identityDictionaryOOP); identityDictionary->tally = FROM_INT (0); return (identityDictionaryOOP); @@ -2022,24 +2015,6 @@ _gst_message_new_args (OOP selectorOOP, } OOP -_gst_directed_message_new_args (OOP receiverOOP, - OOP selectorOOP, - OOP argsArray) -{ - gst_directed_message dirMessage; - OOP dirMessageOOP; - - dirMessage = (gst_directed_message) new_instance (_gst_directed_message_class, - &dirMessageOOP); - - dirMessage->selector = selectorOOP; - dirMessage->args = argsArray; - dirMessage->receiver = receiverOOP; - - return (dirMessageOOP); -} - -OOP _gst_c_object_new_typed (PTR cObjPtr, OOP typeOOP) { --- orig/libgst/dict.h +++ mod/libgst/dict.h @@ -466,13 +466,6 @@ extern OOP _gst_message_new_args (OOP se OOP argsArray) ATTRIBUTE_HIDDEN; -/* Create a new DirectedMessage object for the given RECEIVER, - SELECTOR (a Symbol) and Array of arguments. */ -extern OOP _gst_directed_message_new_args (OOP receiverOOP, - OOP selectorOOP, - OOP argsArray) - ATTRIBUTE_HIDDEN; - /* Returns the name of CLASS_OOP (a Smalltalk Class) */ extern OOP _gst_get_class_symbol (OOP class_oop) ATTRIBUTE_PURE --- orig/libgst/genvm-parse.y +++ mod/libgst/genvm-parse.y @@ -91,7 +91,7 @@ typedef struct table_info { #define YYPRINT(fp, tok, val) yyprint (fp, tok, &val) static int filprintf (Filament *fil, const char *format, ...); -static void yyprint (FILE *fp, int tok, YYSTYPE *val); +static void yyprint (FILE *fp, int tok, const YYSTYPE *val); static void yyerror (const char *s); static operation_info *define_operation (const char *name); static void set_curr_op_stack (id_list *in, id_list *out); @@ -297,7 +297,7 @@ c_code: c_code EXPR %% -void yyprint (FILE *fp, int tok, YYSTYPE *val) +void yyprint (FILE *fp, int tok, const YYSTYPE *val) { switch (tok) { --- orig/libgst/interp.c +++ mod/libgst/interp.c @@ -2128,25 +2128,6 @@ _gst_nvmsg_send (OOP receiver, currentProcessOOP = get_active_process (); change_process_context (processOOP); -#if 0 - if (_gst_kernel_initialized) - { - gst_array argsArray; - OOP argsArrayOOP; - argsArray = new_instance_with (_gst_array_class, numArgs, &argsArrayOOP); - for (i = 0; i < sendArgs; i++) - argsArray->data[i] = args[i]; - - INC_ADD_OOP (argsArrayOOP); - dirMessageOOP = _gst_directed_message_new_args (receiver, sendSelector, argsArrayOOP); - - receiver = _gst_process_class; - sendSelector = _gst_start_execution_symbol; - sendArgs = 1; - args = &dirMessageOOP; - } -#endif - PUSH_OOP (receiver); for (i = 0; i < sendArgs; i++) PUSH_OOP (args[i]); --- orig/libgst/opt.c +++ mod/libgst/opt.c @@ -936,15 +936,15 @@ _gst_compute_stack_positions (gst_uchar } SEND_ARITH { - balance -= _gst_builtin_selectors[n]->numArgs; + balance -= _gst_builtin_selectors[n].numArgs; } SEND_IMMEDIATE { - balance -= super + _gst_builtin_selectors[n]->numArgs; + balance -= super + _gst_builtin_selectors[n].numArgs; } SEND_SPECIAL { - balance -= _gst_builtin_selectors[n + 16]->numArgs; + balance -= _gst_builtin_selectors[n + 16].numArgs; } INVALID { @@ -1392,10 +1392,10 @@ _gst_verify_method (OOP methodOOP, int * } SEND_ARITH { - if (!_gst_builtin_selectors[n]) + if (!_gst_builtin_selectors[n].symbol) return ("invalid immediate send"); - balance -= _gst_builtin_selectors[n]->numArgs; + balance -= _gst_builtin_selectors[n].numArgs; /* Sends touch the new stack top, so they require an extra slot. */ if (curr_sp + balance < 1) @@ -1403,10 +1403,10 @@ _gst_verify_method (OOP methodOOP, int * } SEND_SPECIAL { - if (!_gst_builtin_selectors[n + 16]) + if (!_gst_builtin_selectors[n + 16].symbol) return ("invalid immediate send"); - balance -= _gst_builtin_selectors[n + 16]->numArgs; + balance -= _gst_builtin_selectors[n + 16].numArgs; /* Sends touch the new stack top, so they require an extra slot. */ if (curr_sp + balance < 1) @@ -1414,10 +1414,10 @@ _gst_verify_method (OOP methodOOP, int * } SEND_IMMEDIATE { - if (!_gst_builtin_selectors[n]) + if (!_gst_builtin_selectors[n].symbol) return ("invalid immediate send"); - balance -= super + _gst_builtin_selectors[n]->numArgs; + balance -= super + _gst_builtin_selectors[n].numArgs; /* Sends touch the new stack top, so they require an extra slot. */ if (curr_sp + balance < 1) @@ -1726,11 +1726,11 @@ _gst_verify_method (OOP methodOOP, int * } SEND_ARITH { - sp -= _gst_builtin_selectors[n]->numArgs; + sp -= _gst_builtin_selectors[n].numArgs; sp[-1] = FROM_INT (VARYING); } SEND_SPECIAL { - sp -= _gst_builtin_selectors[n + 16]->numArgs; + sp -= _gst_builtin_selectors[n + 16].numArgs; sp[-1] = FROM_INT (VARYING); } @@ -1769,7 +1769,7 @@ _gst_verify_method (OOP methodOOP, int * return (_gst_debug (), "Invalid send to super"); last_used_literal = NULL; - sp -= super + _gst_builtin_selectors[n]->numArgs; + sp -= super + _gst_builtin_selectors[n].numArgs; if (super && sp[-1] != FROM_INT (SELF)) return ("Invalid send to super"); --- orig/libgst/sym.c +++ mod/libgst/sym.c @@ -94,65 +94,41 @@ typedef struct symbol_info symbol_info; +/* These variables hold various symbols needed mostly by the compiler + and the C interface. It is important that these symbols are *not* + included in the builtin selectors list (builtins.gperf) because + of the way we create symbols in _gst_init_symbols_pass1. */ + OOP _gst_and_symbol = NULL; OOP _gst_as_scaled_decimal_scale_symbol = NULL; -OOP _gst_at_put_symbol = NULL; -OOP _gst_at_symbol = NULL; OOP _gst_bad_return_error_symbol = NULL; -OOP _gst_bit_and_symbol = NULL; -OOP _gst_bit_or_symbol = NULL; -OOP _gst_bit_shift_symbol = NULL; -OOP _gst_bit_xor_symbol = NULL; OOP _gst_boolean_symbol = NULL; OOP _gst_byte_array_out_symbol = NULL; OOP _gst_byte_array_symbol = NULL; OOP _gst_c_object_ptr_symbol = NULL; OOP _gst_c_object_symbol = NULL; OOP _gst_char_symbol = NULL; -OOP _gst_class_symbol = NULL; -OOP _gst_divide_symbol = NULL; OOP _gst_does_not_understand_symbol = NULL; OOP _gst_double_symbol = NULL; -OOP _gst_equal_symbol = NULL; OOP _gst_false_symbol = NULL; OOP _gst_float_symbol = NULL; -OOP _gst_greater_equal_symbol = NULL; -OOP _gst_greater_than_symbol = NULL; OOP _gst_if_false_if_true_symbol = NULL; OOP _gst_if_false_symbol = NULL; OOP _gst_if_true_if_false_symbol = NULL; OOP _gst_if_true_symbol = NULL; OOP _gst_int_symbol = NULL; -OOP _gst_integer_divide_symbol = NULL; -OOP _gst_is_nil_symbol = NULL; -OOP _gst_java_as_int_symbol = NULL; -OOP _gst_java_as_long_symbol = NULL; -OOP _gst_less_equal_symbol = NULL; -OOP _gst_less_than_symbol = NULL; OOP _gst_long_double_symbol = NULL; OOP _gst_long_symbol = NULL; -OOP _gst_minus_symbol = NULL; OOP _gst_must_be_boolean_symbol = NULL; -OOP _gst_new_colon_symbol = NULL; OOP _gst_nil_symbol = NULL; -OOP _gst_not_equal_symbol = NULL; -OOP _gst_not_nil_symbol = NULL; OOP _gst_or_symbol = NULL; -OOP _gst_perform_symbol = NULL; -OOP _gst_perform_with_symbol = NULL; -OOP _gst_perform_with_with_symbol = NULL; -OOP _gst_perform_with_with_with_symbol = NULL; -OOP _gst_perform_with_arguments_symbol = NULL; OOP _gst_permission_symbol = NULL; -OOP _gst_plus_symbol = NULL; OOP _gst_primitive_symbol = NULL; -OOP _gst_remainder_symbol = NULL; OOP _gst_repeat_symbol = NULL; -OOP _gst_same_object_symbol = NULL; OOP _gst_self_smalltalk_symbol = NULL; OOP _gst_self_symbol = NULL; -OOP _gst_size_symbol = NULL; OOP _gst_smalltalk_symbol = NULL; +OOP _gst_smalltalk_namespace_symbol = NULL; OOP _gst_start_execution_symbol = NULL; OOP _gst_string_out_symbol = NULL; OOP _gst_string_symbol = NULL; @@ -161,9 +137,7 @@ OOP _gst_symbol_symbol = NULL; OOP _gst_symbol_out_symbol = NULL; OOP _gst_symbol_table = NULL; OOP _gst_terminate_symbol = NULL; -OOP _gst_this_context_symbol = NULL; OOP _gst_times_repeat_symbol = NULL; -OOP _gst_times_symbol = NULL; OOP _gst_to_by_do_symbol = NULL; OOP _gst_to_do_symbol = NULL; OOP _gst_true_symbol = NULL; @@ -171,8 +145,6 @@ OOP _gst_uint_symbol = NULL; OOP _gst_ulong_symbol = NULL; OOP _gst_undeclared_symbol = NULL; OOP _gst_unknown_symbol = NULL; -OOP _gst_value_colon_symbol = NULL; -OOP _gst_value_symbol = NULL; OOP _gst_value_with_rec_with_args_symbol = NULL; OOP _gst_variadic_smalltalk_symbol = NULL; OOP _gst_variadic_symbol = NULL; @@ -188,7 +160,7 @@ OOP _gst_while_true_symbol = NULL; OOP _gst_current_namespace = NULL; /* The list of selectors for the send immediate bytecode. */ -struct builtin_selector *_gst_builtin_selectors[256] = {}; +struct builtin_selector _gst_builtin_selectors[256] = {}; /* True if undeclared globals can be considered forward references. */ int _gst_use_undeclared = 0; @@ -200,6 +172,15 @@ static mst_Boolean is_same_string (const OOP oop, int len); +/* Allocate memory for a symbol of length LEN and whose contents are STR. + This function does not fill in the object's class because it is called + upon image loading, when the classes have not been initialized yet. */ +static OOP alloc_symbol_oop (const char *str, int len); + +/* Link SYMBOLOOP into the symbol table (using the given hash table index), + and fill the class slot of the symbol. */ +static OOP alloc_symlink (OOP symbolOOP, uintptr_t index); + /* Answer whether C is considered a white space character in Smalltalk programs. */ static mst_Boolean is_white_space (char c); @@ -268,64 +249,35 @@ static scope cur_scope = NULL; static const symbol_info sym_info[] = { {&_gst_and_symbol, "and:"}, {&_gst_as_scaled_decimal_scale_symbol, "asScaledDecimal:scale:"}, - {&_gst_at_put_symbol, "at:put:"}, - {&_gst_at_symbol, "at:"}, {&_gst_bad_return_error_symbol, "badReturnError"}, - {&_gst_bit_and_symbol, "bitAnd:"}, - {&_gst_bit_or_symbol, "bitOr:"}, - {&_gst_bit_xor_symbol, "bitXor:"}, - {&_gst_bit_shift_symbol, "bitShift:"}, {&_gst_byte_array_symbol, "byteArray"}, {&_gst_byte_array_out_symbol, "byteArrayOut"}, {&_gst_boolean_symbol, "boolean"}, {&_gst_char_symbol, "char"}, - {&_gst_class_symbol, "class"}, {&_gst_c_object_symbol, "cObject"}, {&_gst_c_object_ptr_symbol, "cObjectPtr"}, - {&_gst_divide_symbol, "/"}, {&_gst_does_not_understand_symbol, "doesNotUnderstand:"}, {&_gst_float_symbol, "float"}, {&_gst_double_symbol, "double"}, - {&_gst_equal_symbol, "="}, {&_gst_false_symbol, "false"}, - {&_gst_greater_equal_symbol, ">="}, - {&_gst_greater_than_symbol, ">"}, {&_gst_if_false_if_true_symbol, "ifFalse:ifTrue:"}, {&_gst_if_false_symbol, "ifFalse:"}, {&_gst_if_true_if_false_symbol, "ifTrue:ifFalse:"}, {&_gst_if_true_symbol, "ifTrue:"}, - {&_gst_integer_divide_symbol, "//"}, {&_gst_int_symbol, "int"}, {&_gst_uint_symbol, "uInt"}, - {&_gst_is_nil_symbol, "isNil"}, - {&_gst_java_as_int_symbol, "javaAsInt"}, - {&_gst_java_as_long_symbol, "javaAsLong"}, - {&_gst_less_equal_symbol, "<="}, - {&_gst_less_than_symbol, "<"}, {&_gst_long_double_symbol, "longDouble"}, {&_gst_long_symbol, "long"}, {&_gst_ulong_symbol, "uLong"}, - {&_gst_minus_symbol, "-"}, {&_gst_must_be_boolean_symbol, "mustBeBoolean"}, - {&_gst_new_colon_symbol, "new:"}, {&_gst_nil_symbol, "nil"}, - {&_gst_not_equal_symbol, "~="}, - {&_gst_not_nil_symbol, "notNil"}, {&_gst_or_symbol, "or:"}, - {&_gst_perform_symbol, "perform:"}, - {&_gst_perform_with_symbol, "perform:with:"}, - {&_gst_perform_with_with_symbol, "perform:with:with:"}, - {&_gst_perform_with_with_with_symbol, "perform:with:with:with:"}, - {&_gst_perform_with_arguments_symbol, "perform:withArguments:"}, - {&_gst_plus_symbol, "+"}, {&_gst_primitive_symbol, "primitive:"}, - {&_gst_remainder_symbol, "\\\\"}, {&_gst_repeat_symbol, "repeat"}, - {&_gst_same_object_symbol, "=="}, {&_gst_self_symbol, "self"}, {&_gst_self_smalltalk_symbol, "selfSmalltalk"}, - {&_gst_size_symbol, "size"}, {&_gst_smalltalk_symbol, "smalltalk"}, + {&_gst_smalltalk_namespace_symbol, "Smalltalk"}, {&_gst_start_execution_symbol, "startExecution:"}, {&_gst_string_out_symbol, "stringOut"}, {&_gst_string_symbol, "string"}, @@ -333,18 +285,13 @@ static const symbol_info sym_info[] = { {&_gst_symbol_symbol, "symbol"}, {&_gst_symbol_out_symbol, "symbolOut"}, {&_gst_terminate_symbol, "__terminate"}, - {&_gst_this_context_symbol, "thisContext"}, - {&_gst_times_symbol, "*"}, {&_gst_times_repeat_symbol, "timesRepeat:"}, {&_gst_to_by_do_symbol, "to:by:do:"}, {&_gst_to_do_symbol, "to:do:"}, {&_gst_true_symbol, "true"}, {&_gst_undeclared_symbol, "Undeclared"}, {&_gst_unknown_symbol, "unknown"}, - {&_gst_value_colon_symbol, "value:"}, - {&_gst_value_with_rec_with_args_symbol, - "valueWithReceiver:withArguments:"}, - {&_gst_value_symbol, "value"}, + {&_gst_value_with_rec_with_args_symbol, "valueWithReceiver:withArguments:"}, {&_gst_variadic_symbol, "variadic"}, {&_gst_variadic_smalltalk_symbol, "variadicSmalltalk"}, {&_gst_vm_primitives_symbol, "VMPrimitives"}, @@ -659,7 +606,7 @@ _gst_find_variable (symbol_entry * se, fill_symbol_entry (se, SCOPE_SPECIAL, true, symbol, NIL_INDEX, 0); return (true); } - else if (symbol == _gst_this_context_symbol) + else if (symbol == _gst_builtin_selectors[THIS_CONTEXT_SPECIAL].symbol) { fill_symbol_entry (se, SCOPE_SPECIAL, true, symbol, THIS_CONTEXT_INDEX, 0); @@ -1070,19 +1017,41 @@ _gst_intern_string (const char *str) return (intern_counted_string (str, len)); } +static uintptr_t +hash_symbol (const char *str, int len) +{ + uintptr_t index = scramble (_gst_hash_string (str, len)); + return (index & (SYMBOL_TABLE_SIZE - 1)) + 1; +} + +static OOP +alloc_symlink (OOP symbolOOP, uintptr_t index) +{ + gst_symbol symbol; + sym_link link; + OOP linkOOP; + + symbol = (gst_symbol) OOP_TO_OBJ (symbolOOP); + symbol->objClass = _gst_symbol_class; + + link = (sym_link) new_instance (_gst_sym_link_class, &linkOOP); + link->nextLink = ARRAY_AT (_gst_symbol_table, index); + link->symbol = symbolOOP; + ARRAY_AT_PUT (_gst_symbol_table, index, linkOOP); + + return (symbolOOP); +} + static OOP intern_counted_string (const char *str, int len) { uintptr_t index; - sym_link link; - gst_symbol symbol; OOP symbolOOP, linkOOP; + sym_link link; inc_ptr incPtr; - index = scramble (_gst_hash_string (str, len)); - index = (index & (SYMBOL_TABLE_SIZE - 1)) + 1; - + index = hash_symbol (str, len); for (linkOOP = ARRAY_AT (_gst_symbol_table, index); !IS_NIL (linkOOP); linkOOP = link->nextLink) { @@ -1097,22 +1066,31 @@ intern_counted_string (const char *str, #endif incPtr = INC_SAVE_POINTER (); - symbol = (gst_symbol) new_instance_with (_gst_symbol_class, - len, &symbolOOP); - - memcpy (symbol->symString, str, len); - symbolOOP->flags |= F_READONLY; + symbolOOP = alloc_symbol_oop (str, len); INC_ADD_OOP (symbolOOP); - link = (sym_link) new_instance (_gst_sym_link_class, &linkOOP); - link->nextLink = ARRAY_AT (_gst_symbol_table, index); - link->symbol = symbolOOP; - ARRAY_AT_PUT (_gst_symbol_table, index, linkOOP); - + alloc_symlink (symbolOOP, index); INC_RESTORE_POINTER (incPtr); + return (symbolOOP); } +static OOP +alloc_symbol_oop (const char *str, int len) +{ + int numBytes, alignedBytes; + gst_symbol symbol; + OOP symbolOOP; + + numBytes = sizeof(gst_object_header) + len; + alignedBytes = ROUNDED_BYTES (numBytes); + symbol = (gst_symbol) _gst_alloc_obj (alignedBytes, &symbolOOP); + INIT_UNALIGNED_OBJECT (symbolOOP, alignedBytes - numBytes); + + memcpy (symbol->symString, str, len); + symbolOOP->flags |= F_READONLY; + return symbolOOP; +} static mst_Boolean is_same_string (const char *str, @@ -1236,25 +1214,85 @@ _gst_selector_num_args (OOP symbolOOP) return (1); for (numArgs = 0; len;) - { - if (bytes[--len] == ':') - { - numArgs++; - } - } + if (bytes[--len] == ':') + numArgs++; + return (numArgs); } #include "builtins.inl" void -_gst_init_symbols (void) +_gst_init_symbols_pass1 (void) +{ + const symbol_info *si; + struct builtin_selector *bs; + + for (si = sym_info; si->symbolVar; si++) + *si->symbolVar = alloc_symbol_oop (si->value, strlen (si->value)); + + /* Complete gperf's generated table with each symbol's OOP, + and prepare a kind of reverse mapping from the 256 bytecodes + to the hash table entries. */ + for (bs = _gst_builtin_selectors_hash; + bs - _gst_builtin_selectors_hash < + sizeof (_gst_builtin_selectors_hash) / sizeof (_gst_builtin_selectors_hash[0]); + bs++) + if (bs->offset != -1) + { + const char *name = bs->offset + _gst_builtin_selectors_names; + bs->symbol = alloc_symbol_oop (name, strlen (name)); + _gst_builtin_selectors[bs->bytecode] = *bs; + } +} + +void +_gst_init_symbols_pass2 (void) +{ + const symbol_info *si; + struct builtin_selector *bs; + + for (si = sym_info; si->symbolVar; si++) + alloc_symlink (*si->symbolVar, hash_symbol (si->value, strlen (si->value))); + + /* Complete gperf's generated table with each symbol's OOP, + and prepare a kind of reverse mapping from the 256 bytecodes + to the hash table entries. */ + for (bs = _gst_builtin_selectors_hash; + bs - _gst_builtin_selectors_hash < + sizeof (_gst_builtin_selectors_hash) / sizeof (_gst_builtin_selectors_hash[0]); + bs++) + if (bs->offset != -1) + { + const char *name = bs->offset + _gst_builtin_selectors_names; + alloc_symlink (bs->symbol, hash_symbol (name, strlen (name))); + } +} + +static OOP +intern_string_fast (const char *str, OOP *pTestOOP) +{ + int len = strlen (str); + OOP testOOP = *pTestOOP; + + if (is_same_string (str, testOOP, len)) + { + (*pTestOOP)++; + return testOOP; + } + else + return intern_counted_string (str, len); +} + +void +_gst_restore_symbols (void) { const symbol_info *si; struct builtin_selector *bs; + OOP currentOOP = _gst_symbol_table + 1; for (si = sym_info; si->symbolVar; si++) - *si->symbolVar = _gst_intern_string (si->value); + *si->symbolVar = intern_string_fast (si->value, ¤tOOP); /* Complete gperf's generated table with each symbol's OOP, and prepare a kind of reverse mapping from the 256 bytecodes @@ -1266,7 +1304,7 @@ _gst_init_symbols (void) if (bs->offset != -1) { const char *name = bs->offset + _gst_builtin_selectors_names; - bs->symbol = _gst_intern_string (name); - _gst_builtin_selectors[bs->bytecode] = bs; + bs->symbol = intern_string_fast (name, ¤tOOP); + _gst_builtin_selectors[bs->bytecode] = *bs; } } --- orig/libgst/sym.h +++ mod/libgst/sym.h @@ -90,63 +90,34 @@ extern int _gst_use_undeclared extern OOP _gst_and_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_as_scaled_decimal_scale_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_at_put_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_at_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_bad_return_error_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_bit_and_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_bit_or_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_bit_shift_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_bit_xor_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_boolean_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_byte_array_out_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_byte_array_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_c_object_ptr_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_c_object_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_char_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_class_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_divide_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_does_not_understand_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_double_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_equal_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_false_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_float_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_greater_equal_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_greater_than_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_if_false_if_true_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_if_false_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_if_true_if_false_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_if_true_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_int_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_integer_divide_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_is_nil_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_java_as_int_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_java_as_long_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_less_equal_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_less_than_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_long_double_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_long_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_minus_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_must_be_boolean_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_new_colon_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_nil_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_not_equal_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_not_nil_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_or_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_perform_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_perform_with_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_perform_with_with_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_perform_with_with_with_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_perform_with_arguments_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_permission_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_plus_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_primitive_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_remainder_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_repeat_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_same_object_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_self_smalltalk_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_self_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_size_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_smalltalk_symbol ATTRIBUTE_HIDDEN; +extern OOP _gst_smalltalk_namespace_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_start_execution_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_string_out_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_string_symbol ATTRIBUTE_HIDDEN; @@ -156,7 +127,6 @@ extern OOP _gst_symbol_out_symbol ATTRIB extern OOP _gst_terminate_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_this_context_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_times_repeat_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_times_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_to_by_do_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_to_do_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_true_symbol ATTRIBUTE_HIDDEN; @@ -164,8 +134,6 @@ extern OOP _gst_uint_symbol ATTRIBUTE_HI extern OOP _gst_ulong_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_undeclared_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_unknown_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_value_colon_symbol ATTRIBUTE_HIDDEN; -extern OOP _gst_value_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_value_with_rec_with_args_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_variadic_smalltalk_symbol ATTRIBUTE_HIDDEN; extern OOP _gst_variadic_symbol ATTRIBUTE_HIDDEN; @@ -351,10 +319,22 @@ extern void _gst_print_symbols (void) ATTRIBUTE_HIDDEN; /* This routine initializes the variables containing the Symbols - known to the VM. */ -extern void _gst_init_symbols (void) + known to the VM. This one creates the symbol OOPs, which have to + be consecutive in order to speed up the load. */ +extern void _gst_init_symbols_pass1 (void) ATTRIBUTE_HIDDEN; +/* This one creates the SymLink OOPs for the Symbols previously + created. */ +extern void _gst_init_symbols_pass2 (void) + ATTRIBUTE_HIDDEN; + +/* This routine reloads the variables containing the Symbols + known to the VM. It is invocated upon image load. */ +extern void _gst_restore_symbols (void) + ATTRIBUTE_HIDDEN; + + extern void _gst_check_symbol_chain (void) ATTRIBUTE_HIDDEN; @@ -370,7 +350,7 @@ struct builtin_selector { int bytecode; }; -extern struct builtin_selector *_gst_builtin_selectors[256] +extern struct builtin_selector _gst_builtin_selectors[256] ATTRIBUTE_HIDDEN; extern struct builtin_selector *_gst_lookup_builtin_selector (const char *str, --- orig/libgst/vm.def +++ mod/libgst/vm.def @@ -232,7 +232,7 @@ operation PLUS_SPECIAL ( op1 op2 -- op ) INTERP_BASIC_OP (op, op1, op2, iarg1 += iarg2, farg1 + farg2); PREPARE_STACK (); EXPORT_REGS (); - SEND_MESSAGE (_gst_plus_symbol, 1); + SEND_MESSAGE (_gst_builtin_selectors[PLUS_SPECIAL].symbol, 1); IMPORT_REGS (); FETCH (dispatch_vec); } @@ -241,7 +241,7 @@ operation MINUS_SPECIAL ( op1 op2 -- op INTERP_BASIC_OP (op, op1, op2, iarg1 -= iarg2, farg1 - farg2); PREPARE_STACK (); EXPORT_REGS (); - SEND_MESSAGE (_gst_minus_symbol, |
Free forum by Nabble | Edit this page |