[turbofan] Fix escape analysis of sub-word element access.
This fixes data-flow tracking of sub-word (i.e. int8 or int16) element accesses withing the escape analysis. In essense this makes sure that we only ever consider the offset for loads and stores on tracked objects and avoid mangling the offset on untracked ones. R=jarin@chromium.org TEST=cctest/test-api/Fixed[U]Int[8,16]Array Review-Url: https://codereview.chromium.org/2008883002 Cr-Commit-Position: refs/heads/master@{#36573}
This commit is contained in:
parent
b951f7f8f5
commit
5dc6005281
@ -1388,11 +1388,9 @@ void EscapeAnalysis::ProcessLoadField(Node* node) {
|
||||
Node* from = ResolveReplacement(NodeProperties::GetValueInput(node, 0));
|
||||
VirtualState* state = virtual_states_[node->id()];
|
||||
if (VirtualObject* object = GetVirtualObject(state, from)) {
|
||||
if (!object->IsTracked()) return;
|
||||
int offset = OffsetForFieldAccess(node);
|
||||
if (!object->IsTracked() ||
|
||||
static_cast<size_t>(offset) >= object->field_count()) {
|
||||
return;
|
||||
}
|
||||
if (static_cast<size_t>(offset) >= object->field_count()) return;
|
||||
Node* value = object->GetField(offset);
|
||||
if (value) {
|
||||
value = ResolveReplacement(value);
|
||||
@ -1422,11 +1420,9 @@ void EscapeAnalysis::ProcessLoadElement(Node* node) {
|
||||
index_node->opcode() != IrOpcode::kFloat64Constant);
|
||||
if (index.HasValue()) {
|
||||
if (VirtualObject* object = GetVirtualObject(state, from)) {
|
||||
if (!object->IsTracked()) return;
|
||||
int offset = OffsetForElementAccess(node, index.Value());
|
||||
if (!object->IsTracked() ||
|
||||
static_cast<size_t>(offset) >= object->field_count()) {
|
||||
return;
|
||||
}
|
||||
if (static_cast<size_t>(offset) >= object->field_count()) return;
|
||||
Node* value = object->GetField(offset);
|
||||
if (value) {
|
||||
value = ResolveReplacement(value);
|
||||
@ -1456,10 +1452,10 @@ void EscapeAnalysis::ProcessStoreField(Node* node) {
|
||||
ForwardVirtualState(node);
|
||||
Node* to = ResolveReplacement(NodeProperties::GetValueInput(node, 0));
|
||||
VirtualState* state = virtual_states_[node->id()];
|
||||
VirtualObject* obj = GetVirtualObject(state, to);
|
||||
int offset = OffsetForFieldAccess(node);
|
||||
if (obj && obj->IsTracked() &&
|
||||
static_cast<size_t>(offset) < obj->field_count()) {
|
||||
if (VirtualObject* object = GetVirtualObject(state, to)) {
|
||||
if (!object->IsTracked()) return;
|
||||
int offset = OffsetForFieldAccess(node);
|
||||
if (static_cast<size_t>(offset) >= object->field_count()) return;
|
||||
Node* val = ResolveReplacement(NodeProperties::GetValueInput(node, 1));
|
||||
// TODO(mstarzinger): The following is a workaround to not track the code
|
||||
// entry field in virtual JSFunction objects. We only ever store the inner
|
||||
@ -1470,9 +1466,9 @@ void EscapeAnalysis::ProcessStoreField(Node* node) {
|
||||
DCHECK_EQ(JSFunction::kCodeEntryOffset, FieldAccessOf(node->op()).offset);
|
||||
val = slot_not_analyzed_;
|
||||
}
|
||||
if (obj->GetField(offset) != val) {
|
||||
obj = CopyForModificationAt(obj, state, node);
|
||||
obj->SetField(offset, val);
|
||||
if (object->GetField(offset) != val) {
|
||||
object = CopyForModificationAt(object, state, node);
|
||||
object->SetField(offset, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1488,15 +1484,15 @@ void EscapeAnalysis::ProcessStoreElement(Node* node) {
|
||||
index_node->opcode() != IrOpcode::kFloat32Constant &&
|
||||
index_node->opcode() != IrOpcode::kFloat64Constant);
|
||||
VirtualState* state = virtual_states_[node->id()];
|
||||
VirtualObject* obj = GetVirtualObject(state, to);
|
||||
if (index.HasValue()) {
|
||||
int offset = OffsetForElementAccess(node, index.Value());
|
||||
if (obj && obj->IsTracked() &&
|
||||
static_cast<size_t>(offset) < obj->field_count()) {
|
||||
if (VirtualObject* object = GetVirtualObject(state, to)) {
|
||||
if (!object->IsTracked()) return;
|
||||
int offset = OffsetForElementAccess(node, index.Value());
|
||||
if (static_cast<size_t>(offset) >= object->field_count()) return;
|
||||
Node* val = ResolveReplacement(NodeProperties::GetValueInput(node, 2));
|
||||
if (obj->GetField(offset) != val) {
|
||||
obj = CopyForModificationAt(obj, state, node);
|
||||
obj->SetField(offset, val);
|
||||
if (object->GetField(offset) != val) {
|
||||
object = CopyForModificationAt(object, state, node);
|
||||
object->SetField(offset, val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1508,12 +1504,13 @@ void EscapeAnalysis::ProcessStoreElement(Node* node) {
|
||||
to->id(), to->op()->mnemonic(), node->id(), index_node->id(),
|
||||
index_node->op()->mnemonic());
|
||||
}
|
||||
if (obj && obj->IsTracked()) {
|
||||
if (!obj->AllFieldsClear()) {
|
||||
obj = CopyForModificationAt(obj, state, node);
|
||||
obj->ClearAllFields();
|
||||
if (VirtualObject* object = GetVirtualObject(state, to)) {
|
||||
if (!object->IsTracked()) return;
|
||||
if (!object->AllFieldsClear()) {
|
||||
object = CopyForModificationAt(object, state, node);
|
||||
object->ClearAllFields();
|
||||
TRACE("Cleared all fields of @%d:#%d\n",
|
||||
status_analysis_->GetAlias(obj->id()), obj->id());
|
||||
status_analysis_->GetAlias(object->id()), object->id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user