Faster identity-hashcode primitive; fast path now opencoded by the compiler
parent
b551721dd9
commit
2afd7ce244
|
@ -33,6 +33,7 @@ IN: compiler.cfg.intrinsics
|
||||||
{
|
{
|
||||||
{ kernel.private:tag [ drop emit-tag ] }
|
{ kernel.private:tag [ drop emit-tag ] }
|
||||||
{ kernel.private:getenv [ emit-getenv ] }
|
{ kernel.private:getenv [ emit-getenv ] }
|
||||||
|
{ kernel.private:(identity-hashcode) [ drop emit-identity-hashcode ] }
|
||||||
{ math.private:both-fixnums? [ drop emit-both-fixnums? ] }
|
{ math.private:both-fixnums? [ drop emit-both-fixnums? ] }
|
||||||
{ math.private:fixnum+ [ drop emit-fixnum+ ] }
|
{ math.private:fixnum+ [ drop emit-fixnum+ ] }
|
||||||
{ math.private:fixnum- [ drop emit-fixnum- ] }
|
{ math.private:fixnum- [ drop emit-fixnum- ] }
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: namespaces layouts sequences kernel
|
USING: namespaces layouts sequences kernel math accessors
|
||||||
accessors compiler.tree.propagation.info
|
compiler.tree.propagation.info compiler.cfg.stacks
|
||||||
compiler.cfg.stacks compiler.cfg.hats
|
compiler.cfg.hats compiler.cfg.instructions
|
||||||
compiler.cfg.instructions compiler.cfg.utilities ;
|
compiler.cfg.utilities ;
|
||||||
IN: compiler.cfg.intrinsics.misc
|
IN: compiler.cfg.intrinsics.misc
|
||||||
|
|
||||||
: emit-tag ( -- )
|
: emit-tag ( -- )
|
||||||
|
@ -14,3 +14,9 @@ IN: compiler.cfg.intrinsics.misc
|
||||||
swap node-input-infos first literal>>
|
swap node-input-infos first literal>>
|
||||||
[ ds-drop 0 ^^slot-imm ] [ ds-pop ^^offset>slot ^^slot ] if*
|
[ ds-drop 0 ^^slot-imm ] [ ds-pop ^^offset>slot ^^slot ] if*
|
||||||
ds-push ;
|
ds-push ;
|
||||||
|
|
||||||
|
: emit-identity-hashcode ( -- )
|
||||||
|
ds-pop tag-mask get bitnot ^^load-immediate ^^and 0 0 ^^slot-imm
|
||||||
|
hashcode-shift ^^shr-imm
|
||||||
|
^^tag-fixnum
|
||||||
|
ds-push ;
|
||||||
|
|
|
@ -713,4 +713,6 @@ M: bad-executable summary
|
||||||
|
|
||||||
\ profiling { object } { } define-primitive
|
\ profiling { object } { } define-primitive
|
||||||
|
|
||||||
\ identity-hashcode { object } { fixnum } define-primitive
|
\ (identity-hashcode) { object } { fixnum } define-primitive
|
||||||
|
|
||||||
|
\ compute-identity-hashcode { object } { } define-primitive
|
||||||
|
|
|
@ -30,3 +30,5 @@ H{
|
||||||
{ word 12 }
|
{ word 12 }
|
||||||
{ dll 13 }
|
{ dll 13 }
|
||||||
} type-numbers set
|
} type-numbers set
|
||||||
|
|
||||||
|
2 header-bits set
|
||||||
|
|
|
@ -518,7 +518,8 @@ tuple
|
||||||
{ "<callback>" "alien" (( word -- alien )) }
|
{ "<callback>" "alien" (( word -- alien )) }
|
||||||
{ "enable-gc-events" "memory" (( -- )) }
|
{ "enable-gc-events" "memory" (( -- )) }
|
||||||
{ "disable-gc-events" "memory" (( -- events )) }
|
{ "disable-gc-events" "memory" (( -- events )) }
|
||||||
{ "identity-hashcode" "kernel" (( obj -- code )) }
|
{ "(identity-hashcode)" "kernel.private" (( obj -- code )) }
|
||||||
|
{ "compute-identity-hashcode" "kernel.private" (( obj -- )) }
|
||||||
} [ [ first3 ] dip swap make-primitive ] each-index
|
} [ [ first3 ] dip swap make-primitive ] each-index
|
||||||
|
|
||||||
! Bump build number
|
! Bump build number
|
||||||
|
|
|
@ -192,6 +192,16 @@ M: f hashcode* 2drop 31337 ; inline
|
||||||
|
|
||||||
: hashcode ( obj -- code ) 3 swap hashcode* ; inline
|
: hashcode ( obj -- code ) 3 swap hashcode* ; inline
|
||||||
|
|
||||||
|
: identity-hashcode ( obj -- code )
|
||||||
|
dup tag 0 eq? [
|
||||||
|
dup tag 1 eq? [ drop 0 ] [
|
||||||
|
dup (identity-hashcode) dup 0 eq? [
|
||||||
|
drop dup compute-identity-hashcode
|
||||||
|
(identity-hashcode)
|
||||||
|
] [ nip ] if
|
||||||
|
] if
|
||||||
|
] unless ; inline
|
||||||
|
|
||||||
GENERIC: equal? ( obj1 obj2 -- ? )
|
GENERIC: equal? ( obj1 obj2 -- ? )
|
||||||
|
|
||||||
M: object equal? 2drop f ; inline
|
M: object equal? 2drop f ; inline
|
||||||
|
|
|
@ -16,6 +16,8 @@ SYMBOL: type-numbers
|
||||||
|
|
||||||
SYMBOL: mega-cache-size
|
SYMBOL: mega-cache-size
|
||||||
|
|
||||||
|
SYMBOL: header-bits
|
||||||
|
|
||||||
: type-number ( class -- n )
|
: type-number ( class -- n )
|
||||||
type-numbers get at ;
|
type-numbers get at ;
|
||||||
|
|
||||||
|
@ -23,11 +25,14 @@ SYMBOL: mega-cache-size
|
||||||
tag-bits get shift ;
|
tag-bits get shift ;
|
||||||
|
|
||||||
: tag-header ( n -- tagged )
|
: tag-header ( n -- tagged )
|
||||||
2 shift ;
|
header-bits get shift ;
|
||||||
|
|
||||||
: untag-fixnum ( n -- tagged )
|
: untag-fixnum ( n -- tagged )
|
||||||
tag-bits get neg shift ;
|
tag-bits get neg shift ;
|
||||||
|
|
||||||
|
: hashcode-shift ( -- n )
|
||||||
|
tag-bits get header-bits get + ;
|
||||||
|
|
||||||
! We do this in its own compilation unit so that they can be
|
! We do this in its own compilation unit so that they can be
|
||||||
! folded below
|
! folded below
|
||||||
<<
|
<<
|
||||||
|
|
|
@ -19,18 +19,21 @@ void factor_vm::primitive_set_special_object()
|
||||||
void factor_vm::primitive_identity_hashcode()
|
void factor_vm::primitive_identity_hashcode()
|
||||||
{
|
{
|
||||||
cell tagged = dpeek();
|
cell tagged = dpeek();
|
||||||
if(immediate_p(tagged))
|
object *obj = untag<object>(tagged);
|
||||||
drepl(tagged & ~TAG_MASK);
|
drepl(tag_fixnum(obj->hashcode()));
|
||||||
else
|
}
|
||||||
{
|
|
||||||
object *obj = untag<object>(tagged);
|
void factor_vm::compute_identity_hashcode(object *obj)
|
||||||
if(obj->hashcode() == 0)
|
{
|
||||||
{
|
object_counter++;
|
||||||
/* Use megamorphic_cache_misses as a random source of randomness */
|
if(object_counter == 0) object_counter++;
|
||||||
obj->set_hashcode(((cell)obj / block_granularity) ^ dispatch_stats.megamorphic_cache_hits);
|
obj->set_hashcode((cell)obj ^ object_counter);
|
||||||
}
|
}
|
||||||
drepl(tag_fixnum(obj->hashcode()));
|
|
||||||
}
|
void factor_vm::primitive_compute_identity_hashcode()
|
||||||
|
{
|
||||||
|
object *obj = untag<object>(dpop());
|
||||||
|
compute_identity_hashcode(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_set_slot()
|
void factor_vm::primitive_set_slot()
|
||||||
|
|
|
@ -127,6 +127,7 @@ PRIMITIVE_FORWARD(callback)
|
||||||
PRIMITIVE_FORWARD(enable_gc_events)
|
PRIMITIVE_FORWARD(enable_gc_events)
|
||||||
PRIMITIVE_FORWARD(disable_gc_events)
|
PRIMITIVE_FORWARD(disable_gc_events)
|
||||||
PRIMITIVE_FORWARD(identity_hashcode)
|
PRIMITIVE_FORWARD(identity_hashcode)
|
||||||
|
PRIMITIVE_FORWARD(compute_identity_hashcode)
|
||||||
|
|
||||||
const primitive_type primitives[] = {
|
const primitive_type primitives[] = {
|
||||||
primitive_bignum_to_fixnum,
|
primitive_bignum_to_fixnum,
|
||||||
|
@ -290,6 +291,7 @@ const primitive_type primitives[] = {
|
||||||
primitive_enable_gc_events,
|
primitive_enable_gc_events,
|
||||||
primitive_disable_gc_events,
|
primitive_disable_gc_events,
|
||||||
primitive_identity_hashcode,
|
primitive_identity_hashcode,
|
||||||
|
primitive_compute_identity_hashcode,
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,9 @@ struct factor_vm
|
||||||
/* Number of entries in a polymorphic inline cache */
|
/* Number of entries in a polymorphic inline cache */
|
||||||
cell max_pic_size;
|
cell max_pic_size;
|
||||||
|
|
||||||
|
/* Incrementing object counter for identity hashing */
|
||||||
|
cell object_counter;
|
||||||
|
|
||||||
// contexts
|
// contexts
|
||||||
void reset_datastack();
|
void reset_datastack();
|
||||||
void reset_retainstack();
|
void reset_retainstack();
|
||||||
|
@ -122,6 +125,8 @@ struct factor_vm
|
||||||
void primitive_special_object();
|
void primitive_special_object();
|
||||||
void primitive_set_special_object();
|
void primitive_set_special_object();
|
||||||
void primitive_identity_hashcode();
|
void primitive_identity_hashcode();
|
||||||
|
void compute_identity_hashcode(object *obj);
|
||||||
|
void primitive_compute_identity_hashcode();
|
||||||
cell object_size(cell tagged);
|
cell object_size(cell tagged);
|
||||||
cell clone_object(cell obj_);
|
cell clone_object(cell obj_);
|
||||||
void primitive_clone();
|
void primitive_clone();
|
||||||
|
|
Loading…
Reference in New Issue