aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2018-11-30 09:18:51 +0100
committerBenoit Germain <bnt.germain@gmail.com>2018-11-30 09:18:51 +0100
commitc64ad48fdf3aa9505fcf8505c832d1e397d60e85 (patch)
tree4d97ebd28073b81d27c4d22b3bb46d80812e6b5f /src
parentf8a18ec679f0fc4627e95b893bc0d3560052dc64 (diff)
downloadlanes-c64ad48fdf3aa9505fcf8505c832d1e397d60e85.tar.gz
lanes-c64ad48fdf3aa9505fcf8505c832d1e397d60e85.tar.bz2
lanes-c64ad48fdf3aa9505fcf8505c832d1e397d60e85.zip
don't test __lanesignore for POD types (-> slightly faster when trasnfering lots of data)
+ more code refactoring
Diffstat (limited to 'src')
-rw-r--r--src/tools.c164
-rw-r--r--src/universe.h2
2 files changed, 99 insertions, 67 deletions
diff --git a/src/tools.c b/src/tools.c
index 4e893f3..ff23e36 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -49,7 +49,7 @@ THE SOFTWARE.
49 49
50// functions implemented in deep.c 50// functions implemented in deep.c
51extern bool_t copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode mode_); 51extern bool_t copydeep( Universe* U, lua_State* L, lua_State* L2, int index, LookupMode mode_);
52extern void push_registry_subtable( lua_State* L, void* key_); 52extern void push_registry_subtable( lua_State* L, UniqueKey key_);
53 53
54DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); 54DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+");
55 55
@@ -861,29 +861,27 @@ lua_State* luaG_newstate( Universe* U, lua_State* from_, char const* libs_)
861 861
862/*---=== Inter-state copying ===---*/ 862/*---=== Inter-state copying ===---*/
863 863
864#define REG_MTID ( (void*) get_mt_id ) 864// crc64/we of string "REG_MTID" generated at http://www.nitrxgen.net/hashgen/
865static DECLARE_CONST_UNIQUE_KEY( REG_MTID, 0x2e68f9b4751584dc);
865 866
866/* 867/*
867* Get a unique ID for metatable at [i]. 868* Get a unique ID for metatable at [i].
868*/ 869*/
869static uint_t get_mt_id( Universe* U, lua_State* L, int i) 870static lua_Integer get_mt_id( Universe* U, lua_State* L, int i)
870{ 871{
871 uint_t id; 872 lua_Integer id;
872 873
873 i = lua_absindex( L, i); 874 i = lua_absindex( L, i);
874 875
875 STACK_GROW( L, 3); 876 STACK_GROW( L, 3);
876 877
877 STACK_CHECK( L, 0); 878 STACK_CHECK( L, 0);
878 push_registry_subtable( L, REG_MTID); 879 push_registry_subtable( L, REG_MTID); // ... _R[REG_MTID]
879 lua_pushvalue( L, i); 880 lua_pushvalue( L, i); // ... _R[REG_MTID] {mt}
880 lua_rawget( L, -2); 881 lua_rawget( L, -2); // ... _R[REG_MTID] mtk?
881 //
882 // [-2]: reg[REG_MTID]
883 // [-1]: nil/uint
884 882
885 id = (uint_t) lua_tointeger( L, -1); // 0 for nil 883 id = lua_tointeger( L, -1); // 0 for nil
886 lua_pop( L, 1); 884 lua_pop( L, 1); // ... _R[REG_MTID]
887 STACK_MID( L, 1); 885 STACK_MID( L, 1);
888 886
889 if( id == 0) 887 if( id == 0)
@@ -894,15 +892,15 @@ static uint_t get_mt_id( Universe* U, lua_State* L, int i)
894 892
895 /* Create two-way references: id_uint <-> table 893 /* Create two-way references: id_uint <-> table
896 */ 894 */
897 lua_pushvalue( L, i); 895 lua_pushvalue( L, i); // ... _R[REG_MTID] {mt}
898 lua_pushinteger( L, id); 896 lua_pushinteger( L, id); // ... _R[REG_MTID] {mt} id
899 lua_rawset( L, -3); 897 lua_rawset( L, -3); // ... _R[REG_MTID]
900 898
901 lua_pushinteger( L, id); 899 lua_pushinteger( L, id); // ... _R[REG_MTID] id
902 lua_pushvalue( L, i); 900 lua_pushvalue( L, i); // ... _R[REG_MTID] id {mt}
903 lua_rawset( L, -3); 901 lua_rawset( L, -3); // ... _R[REG_MTID]
904 } 902 }
905 lua_pop( L, 1); // remove 'reg[REG_MTID]' reference 903 lua_pop( L, 1); // ...
906 904
907 STACK_END( L, 0); 905 STACK_END( L, 0);
908 906
@@ -1627,34 +1625,35 @@ static void copy_cached_func( Universe* U, lua_State* L2, uint_t L2_cache_i, lua
1627 1625
1628static bool_t push_cached_metatable( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_) 1626static bool_t push_cached_metatable( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum eLookupMode mode_, char const* upName_)
1629{ 1627{
1628 STACK_CHECK( L, 0);
1630 if( lua_getmetatable( L, i)) // ... mt 1629 if( lua_getmetatable( L, i)) // ... mt
1631 { 1630 {
1632 uint_t const mt_id = get_mt_id( U, L, -1); // Unique id for the metatable 1631 lua_Integer const mt_id = get_mt_id( U, L, -1); // Unique id for the metatable
1633 1632
1634 STACK_CHECK( L2, 0); 1633 STACK_CHECK( L2, 0);
1635 STACK_GROW( L2, 4); 1634 STACK_GROW( L2, 4);
1636 // do we already know this metatable? 1635 // do we already know this metatable?
1637 push_registry_subtable( L2, REG_MTID); // rst 1636 push_registry_subtable( L2, REG_MTID); // _R[REG_MTID]
1638 lua_pushinteger( L2, mt_id); // rst id 1637 lua_pushinteger( L2, mt_id); // _R[REG_MTID] id
1639 lua_rawget( L2, -2); // rst mt? 1638 lua_rawget( L2, -2); // _R[REG_MTID] mt?
1640 1639
1641 STACK_MID( L2, 2); 1640 STACK_MID( L2, 2);
1642 1641
1643 if( lua_isnil( L2, -1)) 1642 if( lua_isnil( L2, -1))
1644 { // L2 did not know the metatable 1643 { // L2 did not know the metatable
1645 lua_pop( L2, 1); // rst 1644 lua_pop( L2, 1); // _R[REG_MTID]
1646 if( inter_copy_one( U, L2, L2_cache_i, L, lua_gettop( L), VT_METATABLE, mode_, upName_)) // rst mt 1645 if( inter_copy_one( U, L2, L2_cache_i, L, lua_gettop( L), VT_METATABLE, mode_, upName_)) // _R[REG_MTID] mt
1647 { 1646 {
1648 STACK_MID( L2, 2); 1647 STACK_MID( L2, 2);
1649 // mt_id -> metatable 1648 // mt_id -> metatable
1650 lua_pushinteger( L2, mt_id); // rst mt id 1649 lua_pushinteger( L2, mt_id); // _R[REG_MTID] mt id
1651 lua_pushvalue( L2, -2); // rst mt id mt 1650 lua_pushvalue( L2, -2); // _R[REG_MTID] mt id mt
1652 lua_rawset( L2, -4); // rst mt 1651 lua_rawset( L2, -4); // _R[REG_MTID] mt
1653 1652
1654 // metatable -> mt_id 1653 // metatable -> mt_id
1655 lua_pushvalue( L2, -1); // rst mt mt 1654 lua_pushvalue( L2, -1); // _R[REG_MTID] mt mt
1656 lua_pushinteger( L2, mt_id); // rst mt mt id 1655 lua_pushinteger( L2, mt_id); // _R[REG_MTID] mt mt id
1657 lua_rawset( L2, -4); // rst mt 1656 lua_rawset( L2, -4); // _R[REG_MTID] mt
1658 } 1657 }
1659 else 1658 else
1660 { 1659 {
@@ -1666,8 +1665,10 @@ static bool_t push_cached_metatable( Universe* U, lua_State* L2, uint_t L2_cache
1666 1665
1667 lua_pop( L, 1); // ... 1666 lua_pop( L, 1); // ...
1668 STACK_END( L2, 1); 1667 STACK_END( L2, 1);
1668 STACK_MID( L, 0);
1669 return TRUE; 1669 return TRUE;
1670 } 1670 }
1671 STACK_END( L, 0);
1671 return FALSE; 1672 return FALSE;
1672} 1673}
1673 1674
@@ -1735,23 +1736,14 @@ static void inter_copy_keyvaluepair( Universe* U, lua_State* L2, uint_t L2_cache
1735 } 1736 }
1736} 1737}
1737 1738
1738static bool_t inter_copy_userdata( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt vt, LookupMode mode_, char const* upName_) 1739bool_t copyclone( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt vt, LookupMode mode_, char const* upName_)
1739{ 1740{
1740 STACK_CHECK( L, 0); 1741 STACK_CHECK( L, 0);
1741 STACK_CHECK( L2, 0); 1742 STACK_CHECK( L2, 0);
1742 if( vt == VT_KEY)
1743 {
1744 return FALSE;
1745 }
1746 // Allow only deep userdata entities to be copied across
1747 DEBUGSPEW_CODE( fprintf( stderr, "USERDATA\n"));
1748 if( copydeep( U, L, L2, i, mode_))
1749 {
1750 return TRUE;
1751 }
1752 1743
1753 if( !lua_getmetatable( L, i)) // ... mt? 1744 if( !lua_getmetatable( L, i)) // ... mt?
1754 { 1745 {
1746 STACK_MID( L, 0);
1755 return FALSE; 1747 return FALSE;
1756 } 1748 }
1757 1749
@@ -1759,6 +1751,7 @@ static bool_t inter_copy_userdata( Universe* U, lua_State* L2, uint_t L2_cache_i
1759 if( lua_isnil( L, -1)) 1751 if( lua_isnil( L, -1))
1760 { 1752 {
1761 lua_pop( L, 2); // ... 1753 lua_pop( L, 2); // ...
1754 STACK_MID( L, 0);
1762 return FALSE; 1755 return FALSE;
1763 } 1756 }
1764 1757
@@ -1823,6 +1816,8 @@ static bool_t inter_copy_userdata( Universe* U, lua_State* L2, uint_t L2_cache_i
1823 ASSERT_L( lua_istable( L2, -1)); 1816 ASSERT_L( lua_istable( L2, -1));
1824 lua_setmetatable( L2, -2); // ... u 1817 lua_setmetatable( L2, -2); // ... u
1825 } 1818 }
1819 STACK_MID( L2, 1);
1820 STACK_MID( L, 0);
1826 return TRUE; 1821 return TRUE;
1827 } 1822 }
1828 else 1823 else
@@ -1831,6 +1826,39 @@ static bool_t inter_copy_userdata( Universe* U, lua_State* L2, uint_t L2_cache_i
1831 } 1826 }
1832 } 1827 }
1833 1828
1829 STACK_END( L2, 1);
1830 STACK_END( L, 0);
1831 return FALSE;
1832}
1833
1834static bool_t inter_copy_userdata( Universe* U, lua_State* L2, uint_t L2_cache_i, lua_State* L, uint_t i, enum e_vt vt, LookupMode mode_, char const* upName_)
1835{
1836 STACK_CHECK( L, 0);
1837 STACK_CHECK( L2, 0);
1838 if( vt == VT_KEY)
1839 {
1840 return FALSE;
1841 }
1842 // Allow only deep userdata entities to be copied across
1843 DEBUGSPEW_CODE( fprintf( stderr, "USERDATA\n"));
1844 if( copydeep( U, L, L2, i, mode_))
1845 {
1846 return TRUE;
1847 }
1848
1849 STACK_MID( L, 0);
1850 STACK_MID( L2, 0);
1851
1852 if( copyclone( U, L2, L2_cache_i, L, i, vt, mode_, upName_))
1853 {
1854 STACK_MID( L, 0);
1855 STACK_MID( L2, 1);
1856 return TRUE;
1857 }
1858
1859 STACK_MID( L, 0);
1860 STACK_MID( L2, 0);
1861
1834 // Not a deep or clonable full userdata 1862 // Not a deep or clonable full userdata
1835 if( U->demoteFullUserdata) // attempt demotion to light userdata 1863 if( U->demoteFullUserdata) // attempt demotion to light userdata
1836 { 1864 {
@@ -1841,6 +1869,7 @@ static bool_t inter_copy_userdata( Universe* U, lua_State* L2, uint_t L2_cache_i
1841 { 1869 {
1842 (void) luaL_error( L, "can't copy non-deep full userdata across lanes"); 1870 (void) luaL_error( L, "can't copy non-deep full userdata across lanes");
1843 } 1871 }
1872
1844 STACK_END( L2, 1); 1873 STACK_END( L2, 1);
1845 STACK_END( L, 0); 1874 STACK_END( L, 0);
1846 return TRUE; 1875 return TRUE;
@@ -1994,6 +2023,7 @@ static bool_t inter_copy_one( Universe* U, lua_State* L2, uint_t L2_cache_i, lua
1994{ 2023{
1995 bool_t ret = TRUE; 2024 bool_t ret = TRUE;
1996 int val_type = lua_type( L, i); 2025 int val_type = lua_type( L, i);
2026 static int const pod_mask = (1 << LUA_TNIL) | (1 << LUA_TBOOLEAN) | (1 << LUA_TLIGHTUSERDATA) | (1 << LUA_TNUMBER) | (1 << LUA_TSTRING);
1997 STACK_GROW( L2, 1); 2027 STACK_GROW( L2, 1);
1998 STACK_CHECK( L, 0); // L // L2 2028 STACK_CHECK( L, 0); // L // L2
1999 STACK_CHECK( L2, 0); // L // L2 2029 STACK_CHECK( L2, 0); // L // L2
@@ -2002,16 +2032,19 @@ static bool_t inter_copy_one( Universe* U, lua_State* L2, uint_t L2_cache_i, lua
2002 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth); 2032 DEBUGSPEW_CODE( ++ U->debugspew_indent_depth);
2003 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s %s: " INDENT_END, lua_type_names[val_type], vt_names[vt])); 2033 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%s %s: " INDENT_END, lua_type_names[val_type], vt_names[vt]));
2004 2034
2005 /* Skip the object if it has metatable with { __lanesignore = true } */ 2035 // Non-POD can be skipped if its metatable contains { __lanesignore = true }
2006 if( lua_getmetatable( L, i)) // ... mt 2036 if( ((1 << val_type) & pod_mask) == 0)
2007 { 2037 {
2008 lua_getfield( L, -1, "__lanesignore"); // ... mt ignore? 2038 if( lua_getmetatable( L, i)) // ... mt
2009 if( lua_isboolean( L, -1) && lua_toboolean( L, -1))
2010 { 2039 {
2011 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "__lanesignore -> LUA_TNIL\n" INDENT_END)); 2040 lua_getfield( L, -1, "__lanesignore"); // ... mt ignore?
2012 val_type = LUA_TNIL; 2041 if( lua_isboolean( L, -1) && lua_toboolean( L, -1))
2042 {
2043 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "__lanesignore -> LUA_TNIL\n" INDENT_END));
2044 val_type = LUA_TNIL;
2045 }
2046 lua_pop( L, 2); // ...
2013 } 2047 }
2014 lua_pop( L, 2); // ...
2015 } 2048 }
2016 STACK_MID( L, 0); 2049 STACK_MID( L, 0);
2017 2050
@@ -2112,8 +2145,8 @@ static bool_t inter_copy_one( Universe* U, lua_State* L2, uint_t L2_cache_i, lua
2112*/ 2145*/
2113int luaG_inter_copy( Universe* U, lua_State* L, lua_State* L2, uint_t n, LookupMode mode_) 2146int luaG_inter_copy( Universe* U, lua_State* L, lua_State* L2, uint_t n, LookupMode mode_)
2114{ 2147{
2115 uint_t top_L = lua_gettop( L); 2148 uint_t top_L = lua_gettop( L); // ... {}n
2116 uint_t top_L2 = lua_gettop( L2); 2149 uint_t top_L2 = lua_gettop( L2); // ...
2117 uint_t i, j; 2150 uint_t i, j;
2118 char tmpBuf[16]; 2151 char tmpBuf[16];
2119 char const* pBuf = U->verboseErrors ? tmpBuf : "?"; 2152 char const* pBuf = U->verboseErrors ? tmpBuf : "?";
@@ -2126,9 +2159,11 @@ int luaG_inter_copy( Universe* U, lua_State* L, lua_State* L2, uint_t n, LookupM
2126 { 2159 {
2127 // requesting to copy more than is available? 2160 // requesting to copy more than is available?
2128 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "nothing to copy()\n" INDENT_END)); 2161 DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "nothing to copy()\n" INDENT_END));
2162 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
2129 return -1; 2163 return -1;
2130 } 2164 }
2131 2165
2166 STACK_CHECK( L2, 0);
2132 STACK_GROW( L2, n + 1); 2167 STACK_GROW( L2, n + 1);
2133 2168
2134 /* 2169 /*
@@ -2136,41 +2171,38 @@ int luaG_inter_copy( Universe* U, lua_State* L, lua_State* L2, uint_t n, LookupM
2136 * function entries, avoiding the same entries to be passed on as multiple 2171 * function entries, avoiding the same entries to be passed on as multiple
2137 * copies. ESSENTIAL i.e. for handling upvalue tables in the right manner! 2172 * copies. ESSENTIAL i.e. for handling upvalue tables in the right manner!
2138 */ 2173 */
2139 lua_newtable( L2); 2174 lua_newtable( L2); // ... cache
2140 2175
2176 STACK_CHECK( L, 0);
2141 for( i = top_L - n + 1, j = 1; i <= top_L; ++ i, ++ j) 2177 for( i = top_L - n + 1, j = 1; i <= top_L; ++ i, ++ j)
2142 { 2178 {
2143 if( U->verboseErrors) 2179 if( U->verboseErrors)
2144 { 2180 {
2145 sprintf( tmpBuf, "arg_%d", j); 2181 sprintf( tmpBuf, "arg_%d", j);
2146 } 2182 }
2147 copyok = inter_copy_one( U, L2, top_L2 + 1, L, i, VT_NORMAL, mode_, pBuf); 2183 copyok = inter_copy_one( U, L2, top_L2 + 1, L, i, VT_NORMAL, mode_, pBuf); // ... cache {}n
2148 if( !copyok) 2184 if( !copyok)
2149 { 2185 {
2150 break; 2186 break;
2151 } 2187 }
2152 } 2188 }
2189 STACK_END( L, 0);
2153 2190
2154 DEBUGSPEW_CODE( -- U->debugspew_indent_depth); 2191 DEBUGSPEW_CODE( -- U->debugspew_indent_depth);
2155 2192
2156 /*
2157 * Remove the cache table. Persistent caching would cause i.e. multiple
2158 * messages passed in the same table to use the same table also in receiving
2159 * end.
2160 */
2161 ASSERT_L( (uint_t) lua_gettop( L) == top_L);
2162 if( copyok) 2193 if( copyok)
2163 { 2194 {
2195 STACK_MID( L2, n + 1);
2196 // Remove the cache table. Persistent caching would cause i.e. multiple
2197 // messages passed in the same table to use the same table also in receiving end.
2164 lua_remove( L2, top_L2 + 1); 2198 lua_remove( L2, top_L2 + 1);
2165 ASSERT_L( (uint_t) lua_gettop( L2) == top_L2 + n);
2166 return 0; 2199 return 0;
2167 } 2200 }
2168 else 2201
2169 { 2202 // error -> pop everything from the target state stack
2170 // error -> pop everything from the target state stack 2203 lua_settop( L2, top_L2);
2171 lua_settop( L2, top_L2); 2204 STACK_END( L2, 0);
2172 return -2; 2205 return -2;
2173 }
2174} 2206}
2175 2207
2176 2208
diff --git a/src/universe.h b/src/universe.h
index 8727bf7..0ef5a93 100644
--- a/src/universe.h
+++ b/src/universe.h
@@ -82,7 +82,7 @@ struct s_Universe
82 MUTEX_T deep_lock; 82 MUTEX_T deep_lock;
83 MUTEX_T mtid_lock; 83 MUTEX_T mtid_lock;
84 84
85 int last_mt_id; 85 lua_Integer last_mt_id;
86 86
87#if USE_DEBUG_SPEW 87#if USE_DEBUG_SPEW
88 int debugspew_indent_depth; 88 int debugspew_indent_depth;