1
1
use clru:: { CLruCache , CLruCacheConfig , WeightScale } ;
2
2
use std:: collections:: hash_map:: RandomState ;
3
+ use std:: num:: NonZeroUsize ;
3
4
use wasmer:: Module ;
4
5
6
+ use super :: sized_module:: SizedModule ;
5
7
use crate :: { Checksum , Size , VmError , VmResult } ;
6
- use std:: num:: NonZeroUsize ;
7
8
8
9
// Minimum module size.
9
10
// Based on `examples/module_size.sh`, and the cosmwasm-plus contracts.
@@ -14,12 +15,6 @@ use std::num::NonZeroUsize;
14
15
// Which is a very small percentage (~0.03%) of our typical cache memory budget (2 GB).
15
16
const MINIMUM_MODULE_SIZE : Size = Size :: kibi ( 250 ) ;
16
17
17
- #[ derive( Debug ) ]
18
- struct SizedModule {
19
- pub module : Module ,
20
- pub size : usize ,
21
- }
22
-
23
18
#[ derive( Debug ) ]
24
19
struct SizeScale ;
25
20
@@ -64,16 +59,35 @@ impl InMemoryCache {
64
59
}
65
60
66
61
/// Looks up a module in the cache and creates a new module
67
- pub fn load ( & mut self , checksum : & Checksum ) -> VmResult < Option < Module > > {
62
+ pub fn load ( & mut self , checksum : & Checksum ) -> VmResult < Option < SizedModule > > {
68
63
if let Some ( modules) = & mut self . modules {
69
64
match modules. get ( checksum) {
70
- Some ( sized_module ) => Ok ( Some ( sized_module . module . clone ( ) ) ) ,
65
+ Some ( module ) => Ok ( Some ( module. clone ( ) ) ) ,
71
66
None => Ok ( None ) ,
72
67
}
73
68
} else {
74
69
Ok ( None )
75
70
}
76
71
}
72
+
73
+ /// Returns the number of elements in the cache.
74
+ pub fn len ( & self ) -> usize {
75
+ self . modules
76
+ . as_ref ( )
77
+ . map ( |modules| modules. len ( ) )
78
+ . unwrap_or_default ( )
79
+ }
80
+
81
+ /// Returns cumulative size of all elements in the cache.
82
+ ///
83
+ /// This is based on the values provided with `store`. No actual
84
+ /// memory size is measured here.
85
+ pub fn size ( & self ) -> usize {
86
+ self . modules
87
+ . as_ref ( )
88
+ . map ( |modules| modules. weight ( ) )
89
+ . unwrap_or_default ( )
90
+ }
77
91
}
78
92
79
93
#[ cfg( test) ]
@@ -148,11 +162,131 @@ mod tests {
148
162
149
163
// Ensure cached module can be executed
150
164
{
151
- let instance = WasmerInstance :: new ( & cached, & imports ! { } ) . unwrap ( ) ;
165
+ let instance = WasmerInstance :: new ( & cached. module , & imports ! { } ) . unwrap ( ) ;
152
166
set_remaining_points ( & instance, TESTING_GAS_LIMIT ) ;
153
167
let add_one = instance. exports . get_function ( "add_one" ) . unwrap ( ) ;
154
168
let result = add_one. call ( & [ 42 . into ( ) ] ) . unwrap ( ) ;
155
169
assert_eq ! ( result[ 0 ] . unwrap_i32( ) , 43 ) ;
156
170
}
157
171
}
172
+
173
+ #[ test]
174
+ fn len_works ( ) {
175
+ let mut cache = InMemoryCache :: new ( Size :: mebi ( 2 ) ) ;
176
+
177
+ // Create module
178
+ let wasm1 = wat:: parse_str (
179
+ r#"(module
180
+ (type $t0 (func (param i32) (result i32)))
181
+ (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32)
182
+ get_local $p0
183
+ i32.const 1
184
+ i32.add)
185
+ )"# ,
186
+ )
187
+ . unwrap ( ) ;
188
+ let checksum1 = Checksum :: generate ( & wasm1) ;
189
+ let wasm2 = wat:: parse_str (
190
+ r#"(module
191
+ (type $t0 (func (param i32) (result i32)))
192
+ (func $add_one (export "add_two") (type $t0) (param $p0 i32) (result i32)
193
+ get_local $p0
194
+ i32.const 2
195
+ i32.add)
196
+ )"# ,
197
+ )
198
+ . unwrap ( ) ;
199
+ let checksum2 = Checksum :: generate ( & wasm2) ;
200
+ let wasm3 = wat:: parse_str (
201
+ r#"(module
202
+ (type $t0 (func (param i32) (result i32)))
203
+ (func $add_one (export "add_three") (type $t0) (param $p0 i32) (result i32)
204
+ get_local $p0
205
+ i32.const 3
206
+ i32.add)
207
+ )"# ,
208
+ )
209
+ . unwrap ( ) ;
210
+ let checksum3 = Checksum :: generate ( & wasm3) ;
211
+
212
+ assert_eq ! ( cache. len( ) , 0 ) ;
213
+
214
+ // Add 1
215
+ cache
216
+ . store ( & checksum1, compile ( & wasm1, None ) . unwrap ( ) , 900_000 )
217
+ . unwrap ( ) ;
218
+ assert_eq ! ( cache. len( ) , 1 ) ;
219
+
220
+ // Add 2
221
+ cache
222
+ . store ( & checksum2, compile ( & wasm2, None ) . unwrap ( ) , 900_000 )
223
+ . unwrap ( ) ;
224
+ assert_eq ! ( cache. len( ) , 2 ) ;
225
+
226
+ // Add 3 (pushes out the previous two)
227
+ cache
228
+ . store ( & checksum3, compile ( & wasm3, None ) . unwrap ( ) , 1_500_000 )
229
+ . unwrap ( ) ;
230
+ assert_eq ! ( cache. len( ) , 1 ) ;
231
+ }
232
+
233
+ #[ test]
234
+ fn size_works ( ) {
235
+ let mut cache = InMemoryCache :: new ( Size :: mebi ( 2 ) ) ;
236
+
237
+ // Create module
238
+ let wasm1 = wat:: parse_str (
239
+ r#"(module
240
+ (type $t0 (func (param i32) (result i32)))
241
+ (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32)
242
+ get_local $p0
243
+ i32.const 1
244
+ i32.add)
245
+ )"# ,
246
+ )
247
+ . unwrap ( ) ;
248
+ let checksum1 = Checksum :: generate ( & wasm1) ;
249
+ let wasm2 = wat:: parse_str (
250
+ r#"(module
251
+ (type $t0 (func (param i32) (result i32)))
252
+ (func $add_one (export "add_two") (type $t0) (param $p0 i32) (result i32)
253
+ get_local $p0
254
+ i32.const 2
255
+ i32.add)
256
+ )"# ,
257
+ )
258
+ . unwrap ( ) ;
259
+ let checksum2 = Checksum :: generate ( & wasm2) ;
260
+ let wasm3 = wat:: parse_str (
261
+ r#"(module
262
+ (type $t0 (func (param i32) (result i32)))
263
+ (func $add_one (export "add_three") (type $t0) (param $p0 i32) (result i32)
264
+ get_local $p0
265
+ i32.const 3
266
+ i32.add)
267
+ )"# ,
268
+ )
269
+ . unwrap ( ) ;
270
+ let checksum3 = Checksum :: generate ( & wasm3) ;
271
+
272
+ assert_eq ! ( cache. size( ) , 0 ) ;
273
+
274
+ // Add 1
275
+ cache
276
+ . store ( & checksum1, compile ( & wasm1, None ) . unwrap ( ) , 900_000 )
277
+ . unwrap ( ) ;
278
+ assert_eq ! ( cache. size( ) , 900_000 ) ;
279
+
280
+ // Add 2
281
+ cache
282
+ . store ( & checksum2, compile ( & wasm2, None ) . unwrap ( ) , 800_000 )
283
+ . unwrap ( ) ;
284
+ assert_eq ! ( cache. size( ) , 1_700_000 ) ;
285
+
286
+ // Add 3 (pushes out the previous two)
287
+ cache
288
+ . store ( & checksum3, compile ( & wasm3, None ) . unwrap ( ) , 1_500_000 )
289
+ . unwrap ( ) ;
290
+ assert_eq ! ( cache. size( ) , 1_500_000 ) ;
291
+ }
158
292
}
0 commit comments