]> gitweb.factorcode.org Git - factor.git/commitdiff
Add code heap introspection primitive to VM, and make a code-blocks word in tools...
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Tue, 2 Feb 2010 12:46:17 +0000 (01:46 +1300)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Wed, 3 Feb 2010 10:11:32 +0000 (23:11 +1300)
12 files changed:
basis/stack-checker/known-words/known-words.factor
basis/tools/disassembler/udis/udis.factor
basis/tools/disassembler/utils/utils.factor
basis/tools/memory/memory.factor
basis/tools/memory/summary.txt
core/bootstrap/primitives.factor
vm/arrays.cpp
vm/code_heap.cpp
vm/data_heap.cpp
vm/primitives.cpp
vm/primitives.hpp
vm/vm.hpp

index 21a49beffca986bb526d84b9f5e07c01d914d531..4aecd1376e511f7ad134dfad59ee9f6c3dc7b3b6 100644 (file)
@@ -523,6 +523,9 @@ M: bad-executable summary
 \ data-room { } { byte-array } define-primitive
 \ data-room make-flushable
 
+\ (code-blocks) { } { array } define-primitive
+\ (code-blocks)  make-flushable
+
 \ code-room { } { byte-array } define-primitive
 \ code-room  make-flushable
 
index 82c47a5c84899557046af18d8fc6cf716a95693d..ee77268e2277149fa8d1ff3d55ceffd11a7409f8 100644 (file)
@@ -1,11 +1,10 @@
 ! Copyright (C) 2008, 2010 Slava Pestov, Jorge Acereda Macia.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: tools.disassembler namespaces combinators
-alien alien.syntax alien.c-types lexer parser kernel
-sequences layouts math math.order alien.libraries
-math.parser system make fry arrays libc destructors
-tools.disassembler.utils tools.disassembler.private splitting
-alien.data classes.struct ;
+USING: tools.disassembler namespaces combinators alien
+alien.syntax alien.c-types lexer parser kernel sequences layouts
+math math.order alien.libraries math.parser system make fry
+arrays libc destructors tools.memory tools.disassembler.utils
+tools.disassembler.private splitting alien.data classes.struct ;
 IN: tools.disassembler.udis
 
 <<
@@ -105,7 +104,7 @@ FUNCTION: char* ud_lookup_mnemonic ( int c ) ;
     dup UD_SYN_INTEL ud_set_syntax ;
 
 : with-ud ( quot: ( ud -- ) -- )
-    [ [ [ <ud> ] dip call ] with-destructors ] with-word-entry-points ; inline
+    [ [ [ <ud> ] dip call ] with-destructors ] with-code-blocks ; inline
 
 SINGLETON: udis-disassembler
 
index 60e094ac34e9e42e12c089376bf342b21b62d698..11981c81ae290cfa336602448357f583ca95f2e6 100644 (file)
@@ -1,43 +1,20 @@
-USING: accessors arrays binary-search kernel math math.order
-math.parser namespaces sequences sorting splitting vectors vocabs words ;
+USING: accessors kernel math math.parser prettyprint sequences
+splitting tools.memory ;
 IN: tools.disassembler.utils
 
-SYMBOL: word-entry-points
-SYMBOL: smallest-xt
-SYMBOL: greatest-xt
-
-: (word-entry-points) ( -- assoc )
-    vocabs [ words ] map concat [ [ word-code ] keep 3array ] map
-    [ first ] sort-with ;
+: 0x ( str -- str' ) "0x" prepend ;
 
 : complete-address ( n seq -- str )
-    [ first - ] [ third name>> ] bi
-    over zero? [ nip ] [ swap 16 >base "0x" prepend "+" glue ] if ;
+    [ nip owner>> unparse-short ] [ entry-point>> - ] 2bi
+    [ 16 >base 0x " + " glue ] unless-zero ;
 
-: search-xt ( n -- str/f )
-    dup [ smallest-xt get < ] [ greatest-xt get > ] bi or [
-        drop f
-    ] [
-        word-entry-points get over [ swap first <=> ] curry search nip
-        2dup second <= [
-            [ complete-address ] [ drop f ] if*
-        ] [
-            2drop f
-        ] if
-    ] if ;
+: search-xt ( addr -- str/f )
+    dup lookup-return-address
+    dup [ complete-address ] [ 2drop f ] if ;
 
 : resolve-xt ( str -- str' )
-    [ "0x" prepend ] [ 16 base> ] bi
+    [ 0x ] [ 16 base> ] bi
     [ search-xt [ " (" ")" surround append ] when* ] when* ;
 
 : resolve-call ( str -- str' )
     "0x" split1-last [ resolve-xt "0x" glue ] when* ;
-
-: with-word-entry-points ( quot -- )
-    [
-        (word-entry-points)
-        [ word-entry-points set ]
-        [ first first smallest-xt set ]
-        [ last second greatest-xt set ] tri
-        call
-    ] with-scope ; inline
index 6746031a3d1085d8bd3227ce77ccdcd99853d2d2..dd44b24c3e46268b2bdf762ae62795fb9f19df36 100644 (file)
@@ -1,10 +1,11 @@
-! Copyright (C) 2005, 2009 Slava Pestov.
+! Copyright (C) 2005, 2010 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays assocs classes classes.struct
-combinators combinators.smart continuations fry generalizations
-generic grouping io io.styles kernel make math math.parser
-math.statistics memory namespaces parser prettyprint sequences
-sorting splitting strings system vm words ;
+USING: accessors arrays assocs binary-search classes
+classes.struct combinators combinators.smart continuations fry
+generalizations generic grouping io io.styles kernel make math
+math.order math.parser math.statistics memory memory.private
+layouts namespaces parser prettyprint sequences sorting
+splitting strings system vm words hints hashtables ;
 IN: tools.memory
 
 <PRIVATE
@@ -195,3 +196,72 @@ PRIVATE>
         { "Code heap sweep time:" [ [ code-sweep-time>> ] map-sum nanos>string ] }
         { "Compaction time:" [ [ compaction-time>> ] map-sum nanos>string ] }
     } object-table. ;
+
+SINGLETONS: +unoptimized+ +optimized+ +profiling+ +pic+ ;
+
+TUPLE: code-block
+{ owner read-only }
+{ parameters read-only }
+{ relocation read-only }
+{ type read-only }
+{ size read-only }
+{ entry-point read-only } ;
+
+TUPLE: code-blocks { blocks sliced-groups } { cache hashtable } ;
+
+<PRIVATE
+
+: code-block-type ( n -- type )
+    { +unoptimized+ +optimized+ +profiling+ +pic+ } nth ;
+
+: <code-block> ( seq -- code-block )
+    6 firstn-unsafe {
+        [ ]
+        [ ]
+        [ ]
+        [ code-block-type ]
+        [ ]
+        [ tag-bits get shift ]
+    } spread code-block boa ; inline
+
+: <code-blocks> ( seq -- code-blocks )
+    6 <sliced-groups> H{ } clone \ code-blocks boa ;
+
+SYMBOL: code-heap-start
+SYMBOL: code-heap-end
+
+: in-code-heap? ( address -- ? )
+    code-heap-start get code-heap-end get between? ;
+
+: (lookup-return-address) ( addr seq -- code-block )
+    [ entry-point>> <=> ] with search nip ;
+
+HINTS: (lookup-return-address) code-blocks ;
+
+PRIVATE>
+
+M: code-blocks length blocks>> length ; inline
+
+FROM: sequences.private => nth-unsafe ;
+
+M: code-blocks nth-unsafe
+    [ cache>> ] [ blocks>> ] bi
+    '[ _ nth-unsafe <code-block> ] cache ; inline
+
+INSTANCE: code-blocks immutable-sequence
+
+: code-blocks ( -- blocks )
+    (code-blocks) <code-blocks> ;
+
+: with-code-blocks ( quot -- )
+    [
+        code-blocks
+        [ \ code-blocks set ]
+        [ first entry-point>> code-heap-start set ]
+        [ last [ entry-point>> ] [ size>> ] bi + code-heap-end set ] tri
+        call
+    ] with-scope ; inline
+
+: lookup-return-address ( addr -- code-block )
+    dup in-code-heap?
+    [ \ code-blocks get (lookup-return-address) ] [ drop f ] if ;
index 71a88d92af7ff1a03480733171040b2fc9a3b818..17795228216908f230924c20208a90667773e7d6 100644 (file)
@@ -1 +1 @@
-Heap introspection tools
+Data and code heap introspection tools
index 826da41f954033aa0bc13601a110dadfcee02d41..57035860d80d52229a4849b9ac38f6ccfa54817e 100644 (file)
@@ -506,6 +506,7 @@ tuple
     { "float>bignum" "math.private" "primitive_float_to_bignum" (( x -- y )) }
     { "float>fixnum" "math.private" "primitive_float_to_fixnum" (( x -- y )) }
     { "all-instances" "memory" "primitive_all_instances" (( -- array )) }
+    { "(code-blocks)" "memory.private" "primitive_code_blocks" (( -- array )) }
     { "code-room" "memory" "primitive_code_room" (( -- code-room )) }
     { "compact-gc" "memory" "primitive_compact_gc" (( -- )) }
     { "data-room" "memory" "primitive_data_room" (( -- data-room )) }
index cdfee274c75d09afc561770bdaa1dae38c2b960d..0d599a6c96bffcbed71a21c9c40e2c9d87221b82 100644 (file)
@@ -60,6 +60,19 @@ void factor_vm::primitive_resize_array()
        ctx->push(tag<array>(reallot_array(a.untagged(),capacity)));
 }
 
+cell factor_vm::std_vector_to_array(std::vector<cell> &elements)
+{
+       cell element_count = elements.size();
+       data_roots.push_back(data_root_range(&elements[0],element_count));
+
+       tagged<array> objects(allot_uninitialized_array<array>(element_count));
+       memcpy(objects->data(),&elements[0],element_count * sizeof(cell));
+
+       data_roots.pop_back();
+
+       return objects.value();
+}
+
 void growable_array::add(cell elt_)
 {
        factor_vm *parent = elements.parent;
index 495b167f111adfe7b5409351c0dae1f2e3a52ce2..40fe00b0e9ff6a2ac906ac6ef606887998db6796 100755 (executable)
@@ -202,4 +202,40 @@ void factor_vm::primitive_strip_stack_traces()
        each_code_block(stripper);
 }
 
+struct code_block_accumulator {
+       std::vector<cell> objects;
+
+       void operator()(code_block *compiled, cell size)
+       {
+               objects.push_back(compiled->owner);
+               objects.push_back(compiled->parameters);
+               objects.push_back(compiled->relocation);
+
+               objects.push_back(tag_fixnum(compiled->type()));
+               objects.push_back(tag_fixnum(compiled->size()));
+
+               /* Note: the entry point is always a multiple of the heap
+               alignment (16 bytes). We cannot allocate while iterating
+               through the code heap, so it is not possible to call allot_cell()
+               here. It is OK, however, to add it as if it were a fixnum, and
+               have library code shift it to the left by 4. */
+               cell entry_point = (cell)compiled->entry_point();
+               assert((entry_point & (data_alignment - 1)) == 0);
+               assert((entry_point & TAG_MASK) == FIXNUM_TYPE);
+               objects.push_back(entry_point);
+       }
+};
+
+cell factor_vm::code_blocks()
+{
+       code_block_accumulator accum;
+       each_code_block(accum);
+       return std_vector_to_array(accum.objects);
+}
+
+void factor_vm::primitive_code_blocks()
+{
+       ctx->push(code_blocks());
+}
+
 }
index f5946d648b726953f11eb5124103a1eaf238ede8..d1809f09cebf92d7c1b306f733f9c76b58fe9e78 100755 (executable)
@@ -250,16 +250,7 @@ cell factor_vm::instances(cell type)
 {
        object_accumulator accum(type);
        each_object(accum);
-       cell object_count = accum.objects.size();
-
-       data_roots.push_back(data_root_range(&accum.objects[0],object_count));
-
-       array *objects = allot_array(object_count,false_object);
-       memcpy(objects->data(),&accum.objects[0],object_count * sizeof(cell));
-
-       data_roots.pop_back();
-
-       return tag<array>(objects);
+       return std_vector_to_array(accum.objects);
 }
 
 void factor_vm::primitive_all_instances()
index f288a796c282e6eba79b9341b2bbd8ead4f747b0..1eedab85b8095b8fe0a92d4b2eb7efa2cfdabab8 100644 (file)
@@ -43,6 +43,7 @@ PRIMITIVE(callstack)
 PRIMITIVE(callstack_to_array)
 PRIMITIVE(check_datastack)
 PRIMITIVE(clone)
+PRIMITIVE(code_blocks)
 PRIMITIVE(code_room)
 PRIMITIVE(compact_gc)
 PRIMITIVE(compute_identity_hashcode)
index 1ace3c0f7e7a271ce0498fbc4a8bae819911033f..049b44d389b9b683f4e0adbd87e991d76ae53243 100644 (file)
@@ -39,6 +39,7 @@ DECLARE_PRIMITIVE(callstack)
 DECLARE_PRIMITIVE(callstack_to_array)
 DECLARE_PRIMITIVE(check_datastack)
 DECLARE_PRIMITIVE(clone)
+DECLARE_PRIMITIVE(code_blocks)
 DECLARE_PRIMITIVE(code_room)
 DECLARE_PRIMITIVE(compact_gc)
 DECLARE_PRIMITIVE(compute_identity_hashcode)
index f352f8833d395e9d080a6559d83eb7acc14cd1d7..bdbd465d7848593b2122655f603070be2b587857 100755 (executable)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -348,13 +348,14 @@ struct factor_vm
        void primitive_die();
 
        //arrays
+       inline void set_array_nth(array *array, cell slot, cell value);
        array *allot_array(cell capacity, cell fill_);
        void primitive_array();
        cell allot_array_1(cell obj_);
        cell allot_array_2(cell v1_, cell v2_);
        cell allot_array_4(cell v1_, cell v2_, cell v3_, cell v4_);
        void primitive_resize_array();
-       inline void set_array_nth(array *array, cell slot, cell value);
+       cell std_vector_to_array(std::vector<cell> &elements);
 
        //strings
        cell string_nth(const string *str, cell index);
@@ -521,11 +522,11 @@ struct factor_vm
        code_block *add_code_block(code_block_type type, cell code_, cell labels_, cell owner_, cell relocation_, cell parameters_, cell literals_);
 
        //code heap
-       inline void check_code_pointer(cell ptr)
+       inline void check_code_pointer(cell ptr) { }
+
+       template<typename Iterator> void each_code_block(Iterator &iter)
        {
-       #ifdef FACTOR_DEBUG
-               //assert(in_code_heap_p(ptr));
-       #endif
+               code->allocator->iterate(iter);
        }
 
        void init_code_heap(cell size);
@@ -536,11 +537,8 @@ struct factor_vm
        code_heap_room code_room();
        void primitive_code_room();
        void primitive_strip_stack_traces();
-
-       template<typename Iterator> void each_code_block(Iterator &iter)
-       {
-               code->allocator->iterate(iter);
-       }
+       cell code_blocks();
+       void primitive_code_blocks();
 
        //callbacks
        void init_callbacks(cell size);