[torque] compute fixed-point when typing Torque IR
This is important for transient types, which might be invalidated in a loop syntactically below the vulnerable use. Bug: v8:7793 Change-Id: Ia97c03282eefbc44d54beb8edc61f5d44af2c947 Reviewed-on: https://chromium-review.googlesource.com/c/1331547 Reviewed-by: Daniel Clifford <danno@chromium.org> Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#57478}
This commit is contained in:
parent
d75e327d0f
commit
b50ad96be8
@ -20,13 +20,20 @@ void Block::SetInputTypes(const Stack<const Type*>& input_types) {
|
|||||||
|
|
||||||
DCHECK_EQ(input_types.Size(), input_types_->Size());
|
DCHECK_EQ(input_types.Size(), input_types_->Size());
|
||||||
Stack<const Type*> merged_types;
|
Stack<const Type*> merged_types;
|
||||||
|
bool widened = false;
|
||||||
auto c2_iterator = input_types.begin();
|
auto c2_iterator = input_types.begin();
|
||||||
for (const Type* c1 : *input_types_) {
|
for (const Type* c1 : *input_types_) {
|
||||||
const Type* merged_type = TypeOracle::GetUnionType(c1, *c2_iterator++);
|
const Type* merged_type = TypeOracle::GetUnionType(c1, *c2_iterator++);
|
||||||
|
if (!merged_type->IsSubtypeOf(c1)) {
|
||||||
|
widened = true;
|
||||||
|
}
|
||||||
merged_types.Push(merged_type);
|
merged_types.Push(merged_type);
|
||||||
}
|
}
|
||||||
if (merged_types.Size() == input_types_->Size()) {
|
if (merged_types.Size() == input_types_->Size()) {
|
||||||
input_types_ = merged_types;
|
if (widened) {
|
||||||
|
input_types_ = merged_types;
|
||||||
|
Retype();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,11 +19,15 @@ namespace v8 {
|
|||||||
namespace internal {
|
namespace internal {
|
||||||
namespace torque {
|
namespace torque {
|
||||||
|
|
||||||
|
class ControlFlowGraph;
|
||||||
|
|
||||||
class Block {
|
class Block {
|
||||||
public:
|
public:
|
||||||
explicit Block(size_t id, base::Optional<Stack<const Type*>> input_types,
|
explicit Block(ControlFlowGraph* cfg, size_t id,
|
||||||
|
base::Optional<Stack<const Type*>> input_types,
|
||||||
bool is_deferred)
|
bool is_deferred)
|
||||||
: input_types_(std::move(input_types)),
|
: cfg_(cfg),
|
||||||
|
input_types_(std::move(input_types)),
|
||||||
id_(id),
|
id_(id),
|
||||||
is_deferred_(is_deferred) {}
|
is_deferred_(is_deferred) {}
|
||||||
void Add(Instruction instruction) {
|
void Add(Instruction instruction) {
|
||||||
@ -34,6 +38,12 @@ class Block {
|
|||||||
bool HasInputTypes() const { return input_types_ != base::nullopt; }
|
bool HasInputTypes() const { return input_types_ != base::nullopt; }
|
||||||
const Stack<const Type*>& InputTypes() const { return *input_types_; }
|
const Stack<const Type*>& InputTypes() const { return *input_types_; }
|
||||||
void SetInputTypes(const Stack<const Type*>& input_types);
|
void SetInputTypes(const Stack<const Type*>& input_types);
|
||||||
|
void Retype() {
|
||||||
|
Stack<const Type*> current_stack = InputTypes();
|
||||||
|
for (const Instruction& instruction : instructions()) {
|
||||||
|
instruction.TypeInstruction(¤t_stack, cfg_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<Instruction>& instructions() const { return instructions_; }
|
const std::vector<Instruction>& instructions() const { return instructions_; }
|
||||||
bool IsComplete() const {
|
bool IsComplete() const {
|
||||||
@ -43,6 +53,7 @@ class Block {
|
|||||||
bool IsDeferred() const { return is_deferred_; }
|
bool IsDeferred() const { return is_deferred_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ControlFlowGraph* cfg_;
|
||||||
std::vector<Instruction> instructions_;
|
std::vector<Instruction> instructions_;
|
||||||
base::Optional<Stack<const Type*>> input_types_;
|
base::Optional<Stack<const Type*>> input_types_;
|
||||||
const size_t id_;
|
const size_t id_;
|
||||||
@ -58,7 +69,8 @@ class ControlFlowGraph {
|
|||||||
|
|
||||||
Block* NewBlock(base::Optional<Stack<const Type*>> input_types,
|
Block* NewBlock(base::Optional<Stack<const Type*>> input_types,
|
||||||
bool is_deferred) {
|
bool is_deferred) {
|
||||||
blocks_.emplace_back(next_block_id_++, std::move(input_types), is_deferred);
|
blocks_.emplace_back(this, next_block_id_++, std::move(input_types),
|
||||||
|
is_deferred);
|
||||||
return &blocks_.back();
|
return &blocks_.back();
|
||||||
}
|
}
|
||||||
void PlaceBlock(Block* block) { placed_blocks_.push_back(block); }
|
void PlaceBlock(Block* block) { placed_blocks_.push_back(block); }
|
||||||
|
Loading…
Reference in New Issue
Block a user