OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/signature.h" | 5 #include "src/signature.h" |
6 | 6 |
7 #include "src/bit-vector.h" | 7 #include "src/bit-vector.h" |
8 #include "src/flags.h" | 8 #include "src/flags.h" |
9 #include "src/handles.h" | 9 #include "src/handles.h" |
10 #include "src/zone-containers.h" | 10 #include "src/zone-containers.h" |
(...skipping 1336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1347 error(p->pc(), p->last()->pc, | 1347 error(p->pc(), p->last()->pc, |
1348 "%s[%d] expected type %s, found %s of type %s", | 1348 "%s[%d] expected type %s, found %s of type %s", |
1349 WasmOpcodes::OpcodeName(p->opcode()), p->index - 1, | 1349 WasmOpcodes::OpcodeName(p->opcode()), p->index - 1, |
1350 WasmOpcodes::TypeName(expected), | 1350 WasmOpcodes::TypeName(expected), |
1351 WasmOpcodes::OpcodeName(p->last()->opcode()), | 1351 WasmOpcodes::OpcodeName(p->last()->opcode()), |
1352 WasmOpcodes::TypeName(p->last()->type)); | 1352 WasmOpcodes::TypeName(p->last()->type)); |
1353 } | 1353 } |
1354 } | 1354 } |
1355 | 1355 |
1356 void SetEnv(const char* reason, SsaEnv* env) { | 1356 void SetEnv(const char* reason, SsaEnv* env) { |
| 1357 #if DEBUG |
1357 TRACE(" env = %p, block depth = %d, reason = %s", static_cast<void*>(env), | 1358 TRACE(" env = %p, block depth = %d, reason = %s", static_cast<void*>(env), |
1358 static_cast<int>(blocks_.size()), reason); | 1359 static_cast<int>(blocks_.size()), reason); |
1359 if (FLAG_trace_wasm_decoder && env && env->control) { | 1360 if (FLAG_trace_wasm_decoder && env && env->control) { |
1360 TRACE(", control = "); | 1361 TRACE(", control = "); |
1361 compiler::WasmGraphBuilder::PrintDebugName(env->control); | 1362 compiler::WasmGraphBuilder::PrintDebugName(env->control); |
1362 } | 1363 } |
1363 TRACE("\n"); | 1364 TRACE("\n"); |
| 1365 #endif |
1364 ssa_env_ = env; | 1366 ssa_env_ = env; |
1365 if (builder_) { | 1367 if (builder_) { |
1366 builder_->set_control_ptr(&env->control); | 1368 builder_->set_control_ptr(&env->control); |
1367 builder_->set_effect_ptr(&env->effect); | 1369 builder_->set_effect_ptr(&env->effect); |
1368 } | 1370 } |
1369 } | 1371 } |
1370 | 1372 |
1371 void Goto(SsaEnv* from, SsaEnv* to) { | 1373 void Goto(SsaEnv* from, SsaEnv* to) { |
1372 DCHECK_NOT_NULL(to); | 1374 DCHECK_NOT_NULL(to); |
1373 if (!from->go()) return; | 1375 if (!from->go()) return; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1459 } | 1461 } |
1460 | 1462 |
1461 void PrepareForLoop(const byte* pc, SsaEnv* env) { | 1463 void PrepareForLoop(const byte* pc, SsaEnv* env) { |
1462 if (!env->go()) return; | 1464 if (!env->go()) return; |
1463 env->state = SsaEnv::kMerged; | 1465 env->state = SsaEnv::kMerged; |
1464 if (!builder_) return; | 1466 if (!builder_) return; |
1465 | 1467 |
1466 env->control = builder_->Loop(env->control); | 1468 env->control = builder_->Loop(env->control); |
1467 env->effect = builder_->EffectPhi(1, &env->effect, env->control); | 1469 env->effect = builder_->EffectPhi(1, &env->effect, env->control); |
1468 builder_->Terminate(env->effect, env->control); | 1470 builder_->Terminate(env->effect, env->control); |
| 1471 if (FLAG_wasm_loop_assignment_analysis) { |
| 1472 BitVector* assigned = AnalyzeLoopAssignment(pc); |
| 1473 if (assigned != nullptr) { |
| 1474 // Only introduce phis for variables assigned in this loop. |
| 1475 for (int i = EnvironmentCount() - 1; i >= 0; i--) { |
| 1476 if (!assigned->Contains(i)) continue; |
| 1477 env->locals[i] = builder_->Phi(local_type_vec_[i], 1, &env->locals[i], |
| 1478 env->control); |
| 1479 } |
| 1480 return; |
| 1481 } |
| 1482 } |
| 1483 |
1469 // Conservatively introduce phis for all local variables. | 1484 // Conservatively introduce phis for all local variables. |
1470 for (int i = EnvironmentCount() - 1; i >= 0; i--) { | 1485 for (int i = EnvironmentCount() - 1; i >= 0; i--) { |
1471 env->locals[i] = | 1486 env->locals[i] = |
1472 builder_->Phi(local_type_vec_[i], 1, &env->locals[i], env->control); | 1487 builder_->Phi(local_type_vec_[i], 1, &env->locals[i], env->control); |
1473 } | 1488 } |
1474 } | 1489 } |
1475 | 1490 |
1476 // Create a complete copy of the {from}. | 1491 // Create a complete copy of the {from}. |
1477 SsaEnv* Split(SsaEnv* from) { | 1492 SsaEnv* Split(SsaEnv* from) { |
1478 DCHECK_NOT_NULL(from); | 1493 DCHECK_NOT_NULL(from); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1567 // Keep a stack to model the nesting of expressions. | 1582 // Keep a stack to model the nesting of expressions. |
1568 std::vector<int> arity_stack; | 1583 std::vector<int> arity_stack; |
1569 arity_stack.push_back(OpcodeArity(pc)); | 1584 arity_stack.push_back(OpcodeArity(pc)); |
1570 pc += OpcodeLength(pc); | 1585 pc += OpcodeLength(pc); |
1571 | 1586 |
1572 // Iteratively process all AST nodes nested inside the loop. | 1587 // Iteratively process all AST nodes nested inside the loop. |
1573 while (pc < limit_) { | 1588 while (pc < limit_) { |
1574 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); | 1589 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); |
1575 int arity = 0; | 1590 int arity = 0; |
1576 int length = 1; | 1591 int length = 1; |
| 1592 int assigned_index = -1; |
1577 if (opcode == kExprSetLocal) { | 1593 if (opcode == kExprSetLocal) { |
1578 LocalIndexOperand operand(this, pc); | 1594 LocalIndexOperand operand(this, pc); |
1579 if (assigned->length() > 0 && | 1595 if (assigned->length() > 0 && |
1580 static_cast<int>(operand.index) < assigned->length()) { | 1596 static_cast<int>(operand.index) < assigned->length()) { |
1581 // Unverified code might have an out-of-bounds index. | 1597 // Unverified code might have an out-of-bounds index. |
| 1598 // Ignore out-of-bounds indices, as the main verification will fail. |
1582 assigned->Add(operand.index); | 1599 assigned->Add(operand.index); |
| 1600 assigned_index = operand.index; |
1583 } | 1601 } |
1584 arity = 1; | 1602 arity = 1; |
1585 length = 1 + operand.length; | 1603 length = 1 + operand.length; |
1586 } else { | 1604 } else { |
1587 arity = OpcodeArity(pc); | 1605 arity = OpcodeArity(pc); |
1588 length = OpcodeLength(pc); | 1606 length = OpcodeLength(pc); |
1589 } | 1607 } |
1590 | 1608 |
1591 TRACE("loop-assign module+%-6d %s func+%d: 0x%02x %s (len=%d)\n", | 1609 TRACE("loop-assign module+%-6d %s func+%d: 0x%02x %s", baserel(pc), |
1592 baserel(pc), indentation(), startrel(pc), opcode, | 1610 indentation(), startrel(pc), opcode, |
1593 WasmOpcodes::OpcodeName(opcode), length); | 1611 WasmOpcodes::OpcodeName(opcode)); |
| 1612 |
| 1613 if (assigned_index >= 0) { |
| 1614 TRACE(" (assigned local #%d)\n", assigned_index); |
| 1615 } else { |
| 1616 TRACE("\n"); |
| 1617 } |
| 1618 |
1594 pc += length; | 1619 pc += length; |
1595 arity_stack.push_back(arity); | 1620 arity_stack.push_back(arity); |
1596 while (arity_stack.back() == 0) { | 1621 while (arity_stack.back() == 0) { |
1597 arity_stack.pop_back(); | 1622 arity_stack.pop_back(); |
1598 if (arity_stack.empty()) return assigned; // reached end of loop | 1623 if (arity_stack.empty()) return assigned; // reached end of loop |
1599 arity_stack.back()--; | 1624 arity_stack.back()--; |
1600 } | 1625 } |
1601 } | 1626 } |
1602 return assigned; | 1627 return assigned; |
1603 } | 1628 } |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1697 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 1722 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
1698 const byte* start, const byte* end) { | 1723 const byte* start, const byte* end) { |
1699 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; | 1724 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; |
1700 SR_WasmDecoder decoder(zone, nullptr, body); | 1725 SR_WasmDecoder decoder(zone, nullptr, body); |
1701 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); | 1726 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); |
1702 } | 1727 } |
1703 | 1728 |
1704 } // namespace wasm | 1729 } // namespace wasm |
1705 } // namespace internal | 1730 } // namespace internal |
1706 } // namespace v8 | 1731 } // namespace v8 |
OLD | NEW |