fuzzbug fix
This commit is contained in:
parent
1bd6b25d34
commit
80f7fc8a6c
|
@ -155,12 +155,7 @@ pub fn produce_func_wasm(f: &FunctionBody, body: &SerializedBody, locations: &Lo
|
||||||
wasm.locals
|
wasm.locals
|
||||||
.extend(locations.new_locals.iter().map(|ty| ty_to_valty(*ty)));
|
.extend(locations.new_locals.iter().map(|ty| ty_to_valty(*ty)));
|
||||||
|
|
||||||
let mut next_delete = 0;
|
for operator in &body.operators {
|
||||||
for (index, operator) in body.operators.iter().enumerate() {
|
|
||||||
if next_delete < locations.delete.len() && locations.delete[next_delete] == index {
|
|
||||||
next_delete += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
wasm.translate(operator, locations);
|
wasm.translate(operator, locations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ use super::{SerializedBody, SerializedOperator};
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Locations {
|
pub struct Locations {
|
||||||
pub locations: FxHashMap<(Value, usize), LocalId>,
|
pub locations: FxHashMap<(Value, usize), LocalId>,
|
||||||
pub delete: Vec<usize>,
|
|
||||||
pub new_locals: Vec<wasmparser::Type>,
|
pub new_locals: Vec<wasmparser::Type>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +41,6 @@ impl Locations {
|
||||||
pub fn compute(f: &FunctionBody, body: &SerializedBody) -> Locations {
|
pub fn compute(f: &FunctionBody, body: &SerializedBody) -> Locations {
|
||||||
let mut locations = Locations {
|
let mut locations = Locations {
|
||||||
locations: FxHashMap::default(),
|
locations: FxHashMap::default(),
|
||||||
delete: vec![],
|
|
||||||
new_locals: vec![],
|
new_locals: vec![],
|
||||||
};
|
};
|
||||||
let mut allocator = Allocator {
|
let mut allocator = Allocator {
|
||||||
|
@ -54,7 +52,7 @@ impl Locations {
|
||||||
ends: vec![],
|
ends: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
allocator.compute_spans_and_deleted_ops(&body.operators[..]);
|
allocator.compute_spans(&body.operators[..]);
|
||||||
|
|
||||||
locations
|
locations
|
||||||
}
|
}
|
||||||
|
@ -73,6 +71,14 @@ impl<'a> Allocator<'a> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
log::trace!(
|
||||||
|
"handle_op: at location {} op {:?} reads {:?} writes {:?}",
|
||||||
|
location,
|
||||||
|
op,
|
||||||
|
reads,
|
||||||
|
writes
|
||||||
|
);
|
||||||
|
|
||||||
for (value, index) in reads {
|
for (value, index) in reads {
|
||||||
let span = match self.spans.get_mut(&(value, index)) {
|
let span = match self.spans.get_mut(&(value, index)) {
|
||||||
Some(span) => span,
|
Some(span) => span,
|
||||||
|
@ -81,64 +87,24 @@ impl<'a> Allocator<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
span.end = location + 1;
|
span.end = location + 1;
|
||||||
|
log::trace!(" -> span for {}: {:?}", value, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (value, index) in writes {
|
for (value, index) in writes {
|
||||||
self.spans
|
let span = self.spans.entry((value, index)).or_insert(ValueSpan {
|
||||||
.entry((value, index))
|
value,
|
||||||
.or_insert(ValueSpan {
|
multi_value_index: index,
|
||||||
value,
|
start: location,
|
||||||
multi_value_index: index,
|
end: location + 1,
|
||||||
start: location,
|
});
|
||||||
end: location + 1,
|
span.end = location + 1;
|
||||||
})
|
log::trace!(" -> span for {}: {:?}", value, span);
|
||||||
.end = location + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_spans_and_deleted_ops(&mut self, operators: &[SerializedOperator]) {
|
fn compute_spans(&mut self, operators: &[SerializedOperator]) {
|
||||||
// Delete runs of Set(A), Set(B), Get(B), Get(A): these are
|
// For each operator, get the reads and writes and construct spans.
|
||||||
// stack-neutral sequences.
|
|
||||||
let mut start = None;
|
|
||||||
let mut current_run = vec![];
|
|
||||||
for (index, operator) in operators.iter().enumerate() {
|
for (index, operator) in operators.iter().enumerate() {
|
||||||
match operator {
|
|
||||||
&SerializedOperator::Set(..) if start.is_none() => {
|
|
||||||
start = Some(index);
|
|
||||||
current_run.push(operator.clone());
|
|
||||||
}
|
|
||||||
&SerializedOperator::Set(..) => {
|
|
||||||
current_run.push(operator.clone());
|
|
||||||
}
|
|
||||||
&SerializedOperator::Get(v, i)
|
|
||||||
if start.is_some()
|
|
||||||
&& current_run.last() == Some(&SerializedOperator::Set(v, i)) =>
|
|
||||||
{
|
|
||||||
current_run.pop();
|
|
||||||
if current_run.is_empty() {
|
|
||||||
for i in start.unwrap()..=index {
|
|
||||||
self.locations.delete.push(i);
|
|
||||||
}
|
|
||||||
start = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
current_run.clear();
|
|
||||||
start = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For each non-deleted operator, get the reads and writes and construct spans.
|
|
||||||
let mut next_delete = 0;
|
|
||||||
for (index, operator) in operators.iter().enumerate() {
|
|
||||||
if next_delete < self.locations.delete.len()
|
|
||||||
&& self.locations.delete[next_delete] == index
|
|
||||||
{
|
|
||||||
next_delete += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.handle_op(index, operator);
|
self.handle_op(index, operator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -400,6 +400,7 @@ impl<'a> SerializedBodyContext<'a> {
|
||||||
|
|
||||||
// Now push the args in reverse order.
|
// Now push the args in reverse order.
|
||||||
for &arg in operands.iter().rev() {
|
for &arg in operands.iter().rev() {
|
||||||
|
let arg = self.f.resolve_alias(arg);
|
||||||
match &self.f.values[arg.index()] {
|
match &self.f.values[arg.index()] {
|
||||||
&ValueDef::Operator(op, ..) => {
|
&ValueDef::Operator(op, ..) => {
|
||||||
if op_rematerialize(&op) {
|
if op_rematerialize(&op) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ impl UseCountAnalysis {
|
||||||
for &value in &f.blocks[block].insts {
|
for &value in &f.blocks[block].insts {
|
||||||
if value != Value::undef() {
|
if value != Value::undef() {
|
||||||
let value = f.resolve_alias(value);
|
let value = f.resolve_alias(value);
|
||||||
|
counts.add(value);
|
||||||
if workqueue_set.insert(value) {
|
if workqueue_set.insert(value) {
|
||||||
workqueue.push_back(value);
|
workqueue.push_back(value);
|
||||||
}
|
}
|
||||||
|
@ -34,6 +35,7 @@ impl UseCountAnalysis {
|
||||||
f.blocks[block].terminator.visit_uses(|value| {
|
f.blocks[block].terminator.visit_uses(|value| {
|
||||||
if value != Value::undef() {
|
if value != Value::undef() {
|
||||||
let value = f.resolve_alias(value);
|
let value = f.resolve_alias(value);
|
||||||
|
counts.add(value);
|
||||||
if workqueue_set.insert(value) {
|
if workqueue_set.insert(value) {
|
||||||
workqueue.push_back(value);
|
workqueue.push_back(value);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +44,6 @@ impl UseCountAnalysis {
|
||||||
|
|
||||||
while let Some(value) = workqueue.pop_front() {
|
while let Some(value) = workqueue.pop_front() {
|
||||||
workqueue_set.remove(&value);
|
workqueue_set.remove(&value);
|
||||||
counts.add(value);
|
|
||||||
match &f.values[value.index()] {
|
match &f.values[value.index()] {
|
||||||
&ValueDef::Alias(..) | &ValueDef::Arg(..) | &ValueDef::BlockParam(..) => {}
|
&ValueDef::Alias(..) | &ValueDef::Arg(..) | &ValueDef::BlockParam(..) => {}
|
||||||
&ValueDef::Operator(_op, ref args) => {
|
&ValueDef::Operator(_op, ref args) => {
|
||||||
|
@ -51,7 +52,8 @@ impl UseCountAnalysis {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let arg = f.resolve_alias(arg);
|
let arg = f.resolve_alias(arg);
|
||||||
if counts.use_count[arg.index()] == 0 {
|
counts.add(arg);
|
||||||
|
if counts.use_count[arg.index()] == 1 {
|
||||||
if workqueue_set.insert(arg) {
|
if workqueue_set.insert(arg) {
|
||||||
workqueue.push_back(arg);
|
workqueue.push_back(arg);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +65,8 @@ impl UseCountAnalysis {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let value = f.resolve_alias(value);
|
let value = f.resolve_alias(value);
|
||||||
if counts.use_count[value.index()] == 0 {
|
counts.add(value);
|
||||||
|
if counts.use_count[value.index()] == 1 {
|
||||||
if workqueue_set.insert(value) {
|
if workqueue_set.insert(value) {
|
||||||
workqueue.push_back(value);
|
workqueue.push_back(value);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue