]> gitweb.factorcode.org Git - factor.git/commitdiff
New identity-hashcode primitive
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 11 Nov 2009 03:06:36 +0000 (21:06 -0600)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 11 Nov 2009 03:18:54 +0000 (21:18 -0600)
32 files changed:
basis/bootstrap/image/image.factor
basis/compiler/cfg/cfg.factor
basis/compiler/cfg/value-numbering/expressions/expressions.factor
basis/compiler/tree/tree.factor
basis/cpu/ppc/ppc.factor
basis/cpu/x86/x86.factor
basis/io/launcher/launcher.factor
basis/models/models.factor
basis/serialize/serialize.factor
basis/stack-checker/inlining/inlining.factor
basis/stack-checker/known-words/known-words.factor
basis/stack-checker/values/values.factor
core/bootstrap/primitives.factor
core/destructors/destructors.factor
core/hashtables/hashtables-docs.factor
core/kernel/kernel-docs.factor
core/kernel/kernel-tests.factor
core/kernel/kernel.factor
core/layouts/layouts.factor
vm/allot.hpp
vm/code_block_visitor.hpp
vm/collector.hpp
vm/compaction.cpp
vm/data_heap.cpp
vm/debug.cpp
vm/gc.cpp
vm/image.cpp
vm/layouts.hpp
vm/objects.cpp
vm/primitives.cpp
vm/tagged.hpp
vm/vm.hpp

index 2178b5d4cb45653fc92ba9d29b0cfc252ed88278..b2c7f37013f2ba45f85e8c6afca305325413f434 100644 (file)
@@ -71,6 +71,9 @@ C: <eq-wrapper> eq-wrapper
 M: eq-wrapper equal?
     over eq-wrapper? [ [ obj>> ] bi@ eq? ] [ 2drop f ] if ;
 
+M: eq-wrapper hashcode*
+    nip obj>> identity-hashcode ;
+
 SYMBOL: objects
 
 : cache-eql-object ( obj quot -- value )
@@ -224,9 +227,11 @@ USERENV: undefined-quot 60
 
 : emit-fixnum ( n -- ) tag-fixnum emit ;
 
+: emit-header ( n -- ) tag-header emit ;
+
 : emit-object ( class quot -- addr )
     [ type-number ] dip over here-as
-    [ swap tag-fixnum emit call align-here ] dip ;
+    [ swap emit-header call align-here ] dip ;
     inline
 
 ! Write an object to the image.
@@ -234,7 +239,7 @@ GENERIC: ' ( obj -- ptr )
 
 ! Image header
 
-: emit-header ( -- )
+: emit-image-header ( -- )
     image-magic emit
     image-version emit
     data-base emit ! relocation base at end of header
@@ -518,7 +523,7 @@ M: quotation '
 : build-image ( -- image )
     800000 <vector> image set
     20000 <hashtable> objects set
-    emit-header t, 0, 1, -1,
+    emit-image-header t, 0, 1, -1,
     "Building generic words..." print flush
     remake-generics
     "Serializing words..." print flush
index 369e6ebc32631f8177b338225cc12f8e79da93cb..a595a87b3b781a6a720c857e221c79d07556ecc6 100644 (file)
@@ -4,20 +4,16 @@ USING: kernel math vectors arrays accessors namespaces ;
 IN: compiler.cfg
 
 TUPLE: basic-block < identity-tuple
-{ id integer }
 number
 { instructions vector }
 { successors vector }
 { predecessors vector } ;
 
-M: basic-block hashcode* nip id>> ;
-
 : <basic-block> ( -- bb )
     basic-block new
         V{ } clone >>instructions
         V{ } clone >>successors
-        V{ } clone >>predecessors
-        \ basic-block counter >>id ;
+        V{ } clone >>predecessors ;
 
 TUPLE: cfg { entry basic-block } word label
 spill-area-size reps
index 6534aa74ab07b90f81cafde06e19c216f93d35e2..d2e7c2ac864fd48a0ff07e0ffb3265ead010cdd1 100644 (file)
@@ -27,6 +27,9 @@ C: <reference> reference-expr
 M: reference-expr equal?
     over reference-expr? [ [ value>> ] bi@ eq? ] [ 2drop f ] if ;
 
+M: reference-expr hashcode*
+    nip value>> identity-hashcode ;
+
 : constant>vn ( constant -- vn ) <constant> expr>vn ; inline
 
 GENERIC: >expr ( insn -- expr )
index 7fa096b62392f828aef97bee34568b97cf5c93dd..82b8fbb8434f7ceae30119b96a3675a42bf83eab 100644 (file)
@@ -10,8 +10,6 @@ IN: compiler.tree
 
 TUPLE: node < identity-tuple ;
 
-M: node hashcode* drop node hashcode* ;
-
 TUPLE: #introduce < node out-d ;
 
 : #introduce ( out-d -- node )
index 0f33df8df7cc8a6fef0a8d2effa0ed0cbf08b82b..0fb99374a0700e0a2572f3b1f01b5f1492768e2a 100644 (file)
@@ -373,7 +373,7 @@ M: ppc %set-alien-double -rot STFD ;
     scratch-reg nursery-ptr 0 STW ;
 
 :: store-header ( dst class -- )
-    class type-number tag-fixnum scratch-reg LI
+    class type-number tag-header scratch-reg LI
     scratch-reg dst 0 STW ;
 
 : store-tagged ( dst tag -- )
index a63b92e05081c8abb815b48adaaf13c9e284fc8d..d78d05bac75c51d04cdec4a368768c099e28d230 100644 (file)
@@ -430,7 +430,7 @@ M: x86 %vm-field-ptr ( dst field -- )
     [ [] ] dip data-alignment get align ADD ;
 
 : store-header ( temp class -- )
-    [ [] ] [ type-number tag-fixnum ] bi* MOV ;
+    [ [] ] [ type-number tag-header ] bi* MOV ;
 
 : store-tagged ( dst tag -- )
     type-number OR ;
index 34325780c02b463f55e3a780c729c7af4a2c4ff5..d4bfbb35c227f0a31e4de64ac256e51b81f751f1 100755 (executable)
@@ -82,8 +82,6 @@ SYMBOL: wait-flag
     V{ } clone swap processes get set-at
     wait-flag get-global raise-flag ;
 
-M: process hashcode* handle>> hashcode* ;
-
 : pass-environment? ( process -- ? )
     dup environment>> assoc-empty? not
     swap environment-mode>> +replace-environment+ eq? or ;
index 1c03bb224c0e5a57850efe78e558d6de3bcffde2..f9927cfd4cc181b1f549a59a904117c525498cff 100644 (file)
@@ -17,8 +17,6 @@ value connections dependencies ref locked? ;
 : <model> ( value -- model )
     model new-model ;
 
-M: model hashcode* drop model hashcode* ;
-
 : add-dependency ( dep model -- )
     dependencies>> push ;
 
index 4de858e811182d63593e8e2b32bf0deb951d8cdd..9b4b0ac46b9651be7bd68fafe8668728d35c66bf 100644 (file)
@@ -26,7 +26,7 @@ TUPLE: id obj ;
 
 C: <id> id
 
-M: id hashcode* obj>> hashcode* ;
+M: id hashcode* nip obj>> identity-hashcode ;
 
 M: id equal? over id? [ [ obj>> ] bi@ eq? ] [ 2drop f ] if ;
 
index 2a2f86df3dacc09b3b7925ec9fdc06abdf2e9dc9..38ac2b0e719a24fb66f63e9c35f6dd928da46fab 100644 (file)
@@ -29,8 +29,6 @@ fixed-point
 introductions
 loop? ;
 
-M: inline-recursive hashcode* id>> hashcode* ;
-
 : inlined-block? ( word -- ? ) "inlined-block" word-prop ;
 
 : <inline-recursive> ( word -- label )
index 1a9eb4afa44e65184533ac85ae7b6efd46a9ff1e..01c574295969bbd511a08c5c22da15b00ff36870 100644 (file)
@@ -712,3 +712,5 @@ M: bad-executable summary
 \ disable-gc-events { } { object } define-primitive
 
 \ profiling { object } { } define-primitive
+
+\ identity-hashcode { object } { fixnum } define-primitive
index 97545a872f8c236275413bb647a22741b3d5ba74..7e11ec3edb57a85f51f73e1219e2d5299bdc0eea 100644 (file)
@@ -37,14 +37,14 @@ GENERIC: (input-value?) ( value -- ? )
 GENERIC: (literal) ( known -- literal )
 
 ! Literal value
-TUPLE: literal < identity-tuple value recursion hashcode ;
+TUPLE: literal < identity-tuple value recursion ;
 
 : literal ( value -- literal ) known (literal) ;
 
-M: literal hashcode* nip hashcode>> ;
+M: literal hashcode* nip value>> identity-hashcode ;
 
 : <literal> ( obj -- value )
-    recursive-state get over hashcode \ literal boa ;
+    recursive-state get \ literal boa ;
 
 M: literal (input-value?) drop f ;
 
@@ -55,7 +55,7 @@ M: literal (literal) ;
 : curried/composed-literal ( input1 input2 quot -- literal )
     [ [ literal ] bi@ ] dip
     [ [ [ value>> ] bi@ ] dip call ] [ drop nip recursion>> ] 3bi
-    over hashcode \ literal boa ; inline
+    \ literal boa ; inline
 
 ! Result of curry
 TUPLE: curried obj quot ;
index 702590516cb1ade9ebdc8e90c5831cbc65c605b2..26a5e15d6c1e2d3d8a3d2f73257ba220e469b782 100644 (file)
@@ -518,6 +518,7 @@ tuple
     { "<callback>" "alien" (( word -- alien )) }
     { "enable-gc-events" "memory" (( -- )) }
     { "disable-gc-events" "memory" (( -- events )) }
+    { "identity-hashcode" "kernel" (( obj -- code )) }
 } [ [ first3 ] dip swap make-primitive ] each-index
 
 ! Bump build number
index 3e57f498af6698f28ecd111d60388eafc0982cd9..8cceeefdce9df8c6a150117685ed3298dca5c672 100644 (file)
@@ -26,15 +26,11 @@ SLOT: continuation
 PRIVATE>
 
 TUPLE: disposable < identity-tuple
-{ id integer }
 { disposed boolean }
 continuation ;
 
-M: disposable hashcode* nip id>> ;
-
 : new-disposable ( class -- disposable )
-    new \ disposable counter >>id
-    dup register-disposable ; inline
+    new dup register-disposable ; inline
 
 GENERIC: dispose* ( disposable -- )
 
index 37d6de0a76d37e8db1f7ec8fcc2185d714eccbfb..f2394583551aacc8a68442fd77e528240cf503f5 100755 (executable)
@@ -46,7 +46,8 @@ $nl
 $nl
 "In certain advanced applications, this cannot be avoided and the best design involves mutating hashtable keys. In this case, a custom " { $link hashcode* } " method must be defined which only depends on immutable slots."
 $nl
-"In addition, the " { $link equal? } " and " { $link hashcode* } " methods must be congruent, and if one is defined the other should be defined also. This is documented in detail in the documentation for these respective words." ;
+"In addition, the " { $link equal? } " and " { $link hashcode* } " methods must be congruent, and if one is defined the other should be defined also. This is documented in detail in the documentation for these respective words."
+{ $subsections hashcode hashcode* identity-hashcode } ;
 
 ARTICLE: "hashtables.utilities" "Hashtable utilities"
 "Utility words to create a new hashtable from a single key/value pair:"
index 9a4fd4495ac1c07780227ba2769528f3fc544cb6..0e8c3368ff55a34b047adcae73c3a150f9af1b3b 100644 (file)
@@ -72,7 +72,11 @@ HELP: hashcode
 { $values { "obj" object } { "code" fixnum } }
 { $description "Computes the hashcode of an object with a default hashing depth. See " { $link hashcode* } " for the hashcode contract." } ;
 
-{ hashcode hashcode* } related-words
+HELP: identity-hashcode
+{ $values { "obj" object } { "code" fixnum } }
+{ $description "Outputs the identity hashcode of an object. The identity hashcode is not guaranteed to be unique, however it will not change during the object's lifetime." } ;
+
+{ hashcode hashcode* identity-hashcode } related-words
 
 HELP: =
 { $values { "obj1" object } { "obj2" object } { "?" "a boolean" } }
index 726fa1f5bb95a4d42133e938a27c7035a6ad6528..ded2ee970294496376f419b42a1963ab2c716426 100644 (file)
@@ -169,3 +169,7 @@ IN: kernel.tests
 [ 3 -1 5/6 ] [ 1 2 3 4 5 6 [ + ] [ - ] [ / ] 2tri* ] unit-test
 
 [ { 1 2 } { 3 4 } { 5 6 } ] [ 1 2 3 4 5 6 [ 2array ] 2tri@ ] unit-test
+
+[ t ] [ { } identity-hashcode fixnum? ] unit-test
+[ 123 ] [ 123 identity-hashcode ] unit-test
+[ t ] [ f identity-hashcode fixnum? ] unit-test
index bb27f7e57e499983f0f8dbb971a6ed3033a1da96..58c25732f180a6d1780497330ac73369c0eb573a 100644 (file)
@@ -200,6 +200,8 @@ TUPLE: identity-tuple ;
 
 M: identity-tuple equal? 2drop f ; inline
 
+M: identity-tuple hashcode* nip identity-hashcode ; inline
+
 : = ( obj1 obj2 -- ? )
     2dup eq? [ 2drop t ] [
         2dup both-fixnums? [ 2drop f ] [ equal? ] if
index 7518dbf0cb13e5890e5110c9373f38eaeb0563c6..7ba2bdf8e265d52d18f7022daa26a5cb0f042939 100644 (file)
@@ -22,6 +22,9 @@ SYMBOL: mega-cache-size
 : tag-fixnum ( n -- tagged )
     tag-bits get shift ;
 
+: tag-header ( n -- tagged )
+    2 shift ;
+
 : untag-fixnum ( n -- tagged )
     tag-bits get neg shift ;
 
index 9a00bafd3853ea762f4a0a100249c6add1b3dfc1..2c2c58c2787110e1b9569bcfd308bce7aa384885 100644 (file)
@@ -5,7 +5,7 @@ namespace factor
  * It is up to the caller to fill in the object's fields in a meaningful
  * fashion!
  */
-inline object *factor_vm::allot_object(header header, cell size)
+inline object *factor_vm::allot_object(cell type, cell size)
 {
        /* If the object is smaller than the nursery, allocate it in the nursery,
        after a GC if needed */
@@ -17,13 +17,13 @@ inline object *factor_vm::allot_object(header header, cell size)
 
                object *obj = nursery.allot(size);
 
-               obj->h = header;
+               obj->initialize(type);
                return obj;
        }
        /* If the object is bigger than the nursery, allocate it in
        tenured space */
        else
-               return allot_large_object(header,size);
+               return allot_large_object(type,size);
 }
 
 }
index 0f17d4041dfdbb266ce1f400e414523c48403160..09410d4ae4ed17d3d22f6c454082a06264b7b6f9 100644 (file)
@@ -42,7 +42,7 @@ template<typename Visitor> struct code_block_visitor {
 
        void visit_object_code_block(object *obj)
        {
-               switch(obj->h.hi_tag())
+               switch(obj->type())
                {
                case WORD_TYPE:
                        {
index 2e28da3f49812c2fddad308de19db0c7be80be87..db5b33ba23944884ae32faf093cd504876271915 100644 (file)
@@ -16,11 +16,10 @@ template<typename TargetGeneration, typename Policy> struct collector_workhorse
                parent->check_data_pointer(untagged);
 
                /* is there another forwarding pointer? */
-               while(untagged->h.forwarding_pointer_p())
-                       untagged = untagged->h.forwarding_pointer();
+               while(untagged->forwarding_pointer_p())
+                       untagged = untagged->forwarding_pointer();
 
                /* we've found the destination */
-               untagged->h.check_header();
                return untagged;
        }
 
@@ -32,7 +31,7 @@ template<typename TargetGeneration, typename Policy> struct collector_workhorse
                if(!newpointer) longjmp(parent->current_gc->gc_unwind,1);
 
                memcpy(newpointer,untagged,size);
-               untagged->h.forward_to(newpointer);
+               untagged->forward_to(newpointer);
 
                policy.promoted_object(newpointer);
 
@@ -114,7 +113,7 @@ template<typename TargetGeneration, typename Policy> struct collector {
        void trace_object(object *ptr)
        {
                workhorse.visit_slots(ptr);
-               if(ptr->h.hi_tag() == ALIEN_TYPE)
+               if(ptr->type() == ALIEN_TYPE)
                        ((alien *)ptr)->update_address();
        }
 
index 1c9dfc0defc60178398289465ba6c09acfae9409..0bbc7c8d069a41334beadde0b642feed351de310 100644 (file)
@@ -45,7 +45,7 @@ struct compaction_sizer {
        {
                if(!forwarding_map->marked_p(obj))
                        return forwarding_map->unmarked_block_size(obj);
-               else if(obj->h.hi_tag() == TUPLE_TYPE)
+               else if(obj->type() == TUPLE_TYPE)
                        return align(tuple_size_with_forwarding(forwarding_map,obj),data_alignment);
                else
                        return obj->size();
@@ -72,7 +72,7 @@ struct object_compaction_updater {
        void operator()(object *old_address, object *new_address, cell size)
        {
                cell payload_start;
-               if(old_address->h.hi_tag() == TUPLE_TYPE)
+               if(old_address->type() == TUPLE_TYPE)
                        payload_start = tuple_size_with_forwarding(data_forwarding_map,old_address);
                else
                        payload_start = old_address->binary_payload_start();
index c62b433af07ca61a8ad8819f9bcf809efe57404c..43fbd930f1b5fb6caac4894091da0f738d97d156 100755 (executable)
@@ -126,7 +126,7 @@ cell object::size() const
 {
        if(free_p()) return ((free_heap_block *)this)->size();
 
-       switch(h.hi_tag())
+       switch(type())
        {
        case ARRAY_TYPE:
                return align(array_size((array*)this),data_alignment);
@@ -166,7 +166,7 @@ the GC. Some types have a binary payload at the end (string, word, DLL) which
 we ignore. */
 cell object::binary_payload_start() const
 {
-       switch(h.hi_tag())
+       switch(type())
        {
        /* these objects do not refer to other objects at all */
        case FLOAT_TYPE:
@@ -234,7 +234,7 @@ struct object_accumulator {
 
        void operator()(object *obj)
        {
-               if(type == TYPE_COUNT || obj->h.hi_tag() == type)
+               if(type == TYPE_COUNT || obj->type() == type)
                        objects.push_back(tag_dynamic(obj));
        }
 };
index df2361541956ec2016f51864fc378efb97469fb4..376b9b8346fecbb539bbee8ba44b89738968a4f6 100755 (executable)
@@ -243,7 +243,7 @@ struct object_dumper {
 
        void operator()(object *obj)
        {
-               if(type == TYPE_COUNT || obj->h.hi_tag() == type)
+               if(type == TYPE_COUNT || obj->type() == type)
                {
                        std::cout << padded_address((cell)obj) << " ";
                        parent->print_nested_obj(tag_dynamic(obj),2);
index 977266bd7d7c0afdef6092bf4b554d03e997ecbd..a9372535d45ad3cedf4762bd7af42b17b6958f89 100755 (executable)
--- a/vm/gc.cpp
+++ b/vm/gc.cpp
@@ -234,7 +234,7 @@ VM_C_API void inline_gc(cell *data_roots_base, cell data_roots_size, factor_vm *
  * It is up to the caller to fill in the object's fields in a meaningful
  * fashion!
  */
-object *factor_vm::allot_large_object(header header, cell size)
+object *factor_vm::allot_large_object(cell type, cell size)
 {
        /* If tenured space does not have enough room, collect and compact */
        if(!data->tenured->can_allot_p(size))
@@ -257,7 +257,7 @@ object *factor_vm::allot_large_object(header header, cell size)
        a nursery allocation */
        write_barrier(obj,size);
 
-       obj->h = header;
+       obj->initialize(type);
        return obj;
 }
 
index be6cd813fc21978d610ca5409d1063e471ba6c17..0a84c2d3374d2e5a2e27897d24f20d2cdd8a4b6a 100755 (executable)
@@ -135,12 +135,12 @@ void factor_vm::relocate_object(object *object,
        cell data_relocation_base,
        cell code_relocation_base)
 {
-       cell hi_tag = object->h.hi_tag();
+       cell type = object->type();
        
        /* Tuple relocation is a bit trickier; we have to fix up the
        layout object before we can get the tuple size, so do_slots is
        out of the question */
-       if(hi_tag == TUPLE_TYPE)
+       if(type == TUPLE_TYPE)
        {
                tuple *t = (tuple *)object;
                data_fixup(&t->layout,data_relocation_base);
@@ -156,7 +156,7 @@ void factor_vm::relocate_object(object *object,
                object_fixupper fixupper(this,data_relocation_base);
                do_slots(object,fixupper);
 
-               switch(hi_tag)
+               switch(type)
                {
                case WORD_TYPE:
                        fixup_word((word *)object,code_relocation_base);
index 831cc387d242d70822bd83512602dd40e4cbd1a4..f9aace963b032d277b80c744ee1111fac58b43f2 100644 (file)
@@ -51,8 +51,6 @@ static const cell data_alignment = 16;
 
 #define TYPE_COUNT 14
 
-#define FORWARDING_POINTER 5 /* can be anything other than FIXNUM_TYPE */
-
 enum code_block_type
 {
        code_block_unoptimized,
@@ -95,59 +93,57 @@ inline static cell tag_fixnum(fixnum untagged)
 
 struct object;
 
-struct header {
-       cell value;
+#define NO_TYPE_CHECK static const cell type_number = TYPE_COUNT
 
-        /* Default ctor to make gcc 3.x happy */
-        explicit header() { abort(); }
+struct object {
+       NO_TYPE_CHECK;
+       cell header;
 
-       explicit header(cell value_) : value(value_ << TAG_BITS) {}
+       cell size() const;
+       cell binary_payload_start() const;
+
+       cell *slots()  const { return (cell *)this; }
 
-       void check_header() const
+       /* Only valid for objects in tenured space; must cast to free_heap_block
+       to do anything with it if its free */
+       bool free_p() const
        {
-#ifdef FACTOR_DEBUG
-               assert(TAG(value) == FIXNUM_TYPE && untag_fixnum(value) < TYPE_COUNT);
-#endif
+               return (header & 1) == 1;
        }
 
-       cell hi_tag() const
+       cell type() const
        {
-               check_header();
-               return value >> TAG_BITS;
+               return (header >> 2) & TAG_MASK;
        }
 
-       bool forwarding_pointer_p() const
+       void initialize(cell type)
        {
-               return TAG(value) == FORWARDING_POINTER;
+               header = type << 2;
        }
 
-       object *forwarding_pointer() const
+       cell hashcode() const
        {
-               return (object *)UNTAG(value);
+               return (header >> 6);
        }
 
-       void forward_to(object *pointer)
+       void set_hashcode(cell hashcode)
        {
-               value = RETAG(pointer,FORWARDING_POINTER);
+               header = (header & 0x3f) | (hashcode << 6);
        }
-};
 
-#define NO_TYPE_CHECK static const cell type_number = TYPE_COUNT
-
-struct object {
-       NO_TYPE_CHECK;
-       header h;
-
-       cell size() const;
-       cell binary_payload_start() const;
+       bool forwarding_pointer_p() const
+       {
+               return (header & 2) == 2;
+       }
 
-       cell *slots()  const { return (cell *)this; }
+       object *forwarding_pointer() const
+       {
+               return (object *)UNTAG(header);
+       }
 
-       /* Only valid for objects in tenured space; must fast to free_heap_block
-       to do anything with it if its free */
-       bool free_p() const
+       void forward_to(object *pointer)
        {
-               return (h.value & 1) == 1;
+               header = ((cell)pointer | 2);
        }
 };
 
index fa2446d54f1f5d1f2aad2dd1144492db7116b710..81ba63a616f948804540fa1d9b55a04795cc6fc2 100644 (file)
@@ -16,6 +16,23 @@ void factor_vm::primitive_set_special_object()
        special_objects[e] = value;
 }
 
+void factor_vm::primitive_identity_hashcode()
+{
+       cell tagged = dpeek();
+       if(immediate_p(tagged))
+               drepl(tagged & ~TAG_MASK);
+       else
+       {
+               object *obj = untag<object>(tagged);
+               if(obj->hashcode() == 0)
+               {
+                       /* Use megamorphic_cache_misses as a random source of randomness */
+                       obj->set_hashcode(((cell)obj / block_granularity) ^ dispatch_stats.megamorphic_cache_hits);
+               }
+               drepl(tag_fixnum(obj->hashcode()));
+       }
+}
+
 void factor_vm::primitive_set_slot()
 {
        fixnum slot = untag_fixnum(dpop());
@@ -36,8 +53,9 @@ cell factor_vm::clone_object(cell obj_)
        else
        {
                cell size = object_size(obj.value());
-               object *new_obj = allot_object(header(obj.type()),size);
+               object *new_obj = allot_object(obj.type(),size);
                memcpy(new_obj,obj.untagged(),size);
+               new_obj->set_hashcode(0);
                return tag_dynamic(new_obj);
        }
 }
index 013250a502dc924e01f62ad5a32c6df07f841145..20860af084160511165401dea5d509b3e1555919 100644 (file)
@@ -126,6 +126,7 @@ PRIMITIVE_FORWARD(strip_stack_traces)
 PRIMITIVE_FORWARD(callback)
 PRIMITIVE_FORWARD(enable_gc_events)
 PRIMITIVE_FORWARD(disable_gc_events)
+PRIMITIVE_FORWARD(identity_hashcode)
 
 const primitive_type primitives[] = {
        primitive_bignum_to_fixnum,
@@ -288,6 +289,7 @@ const primitive_type primitives[] = {
        primitive_callback,
        primitive_enable_gc_events,
        primitive_disable_gc_events,
+       primitive_identity_hashcode,
 };
 
 }
index e520e326fa95325787f947d0366844552a77ba8f..e9f89528bc3b0f68c6bd18240b9ae8e59590e32f 100755 (executable)
@@ -8,7 +8,7 @@ template<typename Type> cell tag(Type *value)
 
 inline static cell tag_dynamic(object *value)
 {
-       return RETAG(value,value->h.hi_tag());
+       return RETAG(value,value->type());
 }
 
 template<typename Type>
index 05f15af560d8031e4761727c3df698a260273531..8d7ef556bd07eddcf6b5a32dd80efa1b4806f448 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -121,6 +121,7 @@ struct factor_vm
        // objects
        void primitive_special_object();
        void primitive_set_special_object();
+       void primitive_identity_hashcode();
        cell object_size(cell tagged);
        cell clone_object(cell obj_);
        void primitive_clone();
@@ -284,12 +285,12 @@ struct factor_vm
        void inline_gc(cell *data_roots_base, cell data_roots_size);
        void primitive_enable_gc_events();
        void primitive_disable_gc_events();
-       object *allot_object(header header, cell size);
-       object *allot_large_object(header header, cell size);
+       object *allot_object(cell type, cell size);
+       object *allot_large_object(cell type, cell size);
 
        template<typename Type> Type *allot(cell size)
        {
-               return (Type *)allot_object(header(Type::type_number),size);
+               return (Type *)allot_object(Type::type_number,size);
        }
 
        inline void check_data_pointer(object *pointer)