| 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 |