@@ -39,8 +39,6 @@ impl RegionInternal for MmapRegion {
39
39
module. validate_runtime_spec ( limits) ?;
40
40
41
41
for ( ptr, len) in [
42
- // make the heap read/writable and record its initial size
43
- ( slot. heap , module. heap_spec ( ) . initial_size as usize ) ,
44
42
// make the stack read/writable
45
43
( slot. stack , limits. stack_size ) ,
46
44
// make the globals read/writable
@@ -54,6 +52,8 @@ impl RegionInternal for MmapRegion {
54
52
unsafe { mprotect ( * ptr, * len, ProtFlags :: PROT_READ | ProtFlags :: PROT_WRITE ) ? } ;
55
53
}
56
54
55
+ // note: the initial heap will be made read/writable when `new_instance_handle` calls `reset`
56
+
57
57
let inst_ptr = slot. start as * mut Instance ;
58
58
59
59
// upgrade the slot's weak region pointer so the region can't get dropped while the instance
@@ -66,7 +66,7 @@ impl RegionInternal for MmapRegion {
66
66
. expect ( "backing region of slot (`self`) exists" ) ;
67
67
68
68
let alloc = Alloc {
69
- heap_accessible_size : module . heap_spec ( ) . initial_size as usize ,
69
+ heap_accessible_size : 0 , // the `reset` call in `new_instance_handle` will set this
70
70
heap_inaccessible_size : slot. limits . heap_address_space_size ,
71
71
slot : Some ( slot) ,
72
72
region,
@@ -119,29 +119,32 @@ impl RegionInternal for MmapRegion {
119
119
}
120
120
121
121
fn reset_heap ( & self , alloc : & mut Alloc , module : & dyn Module ) -> Result < ( ) , Error > {
122
+ let heap = alloc. slot ( ) . heap ;
123
+
124
+ if alloc. heap_accessible_size > 0 {
125
+ // zero the whole heap, if any of it is currently accessible
126
+ let heap_size = alloc. slot ( ) . limits . heap_address_space_size ;
127
+
128
+ unsafe {
129
+ mprotect ( heap, heap_size, ProtFlags :: PROT_NONE ) ?;
130
+ madvise ( heap, heap_size, MmapAdvise :: MADV_DONTNEED ) ?;
131
+ }
132
+ }
133
+
122
134
let initial_size = module. heap_spec ( ) . initial_size as usize ;
123
135
124
- // reset the heap to the initial size
136
+ // reset the heap to the initial size, and mprotect those pages appropriately
125
137
if alloc. heap_accessible_size != initial_size {
138
+ unsafe {
139
+ mprotect (
140
+ heap,
141
+ initial_size,
142
+ ProtFlags :: PROT_READ | ProtFlags :: PROT_WRITE ,
143
+ ) ?
144
+ } ;
126
145
alloc. heap_accessible_size = initial_size;
127
146
alloc. heap_inaccessible_size =
128
147
alloc. slot ( ) . limits . heap_address_space_size - initial_size;
129
-
130
- // turn off any extra pages
131
- let acc_heap_end =
132
- ( alloc. slot ( ) . heap as usize + alloc. heap_accessible_size ) as * mut c_void ;
133
- unsafe {
134
- mprotect (
135
- acc_heap_end,
136
- alloc. heap_inaccessible_size ,
137
- ProtFlags :: PROT_NONE ,
138
- ) ?;
139
- madvise (
140
- acc_heap_end,
141
- alloc. heap_inaccessible_size ,
142
- MmapAdvise :: MADV_DONTNEED ,
143
- ) ?;
144
- }
145
148
}
146
149
147
150
// Initialize the heap using the module sparse page data. There cannot be more pages in the
@@ -171,12 +174,6 @@ impl RegionInternal for MmapRegion {
171
174
if let Some ( contents) = module. get_sparse_page_data ( page_num) {
172
175
// otherwise copy in the page data
173
176
heap[ page_base..page_base + host_page_size ( ) ] . copy_from_slice ( contents) ;
174
- } else {
175
- // zero this page
176
- // TODO would using a memset primitive be better here?
177
- for b in heap[ page_base..page_base + host_page_size ( ) ] . iter_mut ( ) {
178
- * b = 0x00 ;
179
- }
180
177
}
181
178
}
182
179
0 commit comments