[turbofan] Support for ConsString by escape analysis.

This add support for ConsString objects allocated inline to the escape
analysis pass. The raw hash field in such strings needs special handling
similar to existing raw fields. This also contains materialization code
within the deoptimizer as usual.

R=bmeurer@chromium.org
TEST=mjsunit/regress/regress-crbug-648737
BUG=chromium:648737

Review-Url: https://codereview.chromium.org/2357153002
Cr-Commit-Position: refs/heads/master@{#39594}
This commit is contained in:
mstarzinger 2016-09-21 05:29:02 -07:00 committed by Commit bot
parent 14a87d9639
commit b097c6c4f1
3 changed files with 47 additions and 5 deletions

View File

@ -1457,13 +1457,13 @@ void EscapeAnalysis::ProcessStoreField(Node* node) {
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
// pointer into the compile lazy stub in this field and the deoptimizer has
// this assumption hard-coded in {TranslatedState::MaterializeAt} as well.
// TODO(mstarzinger): The following is a workaround to not track some well
// known raw fields. We only ever store default initial values into these
// fields which are hard-coded in {TranslatedState::MaterializeAt} as well.
if (val->opcode() == IrOpcode::kInt32Constant ||
val->opcode() == IrOpcode::kInt64Constant) {
DCHECK_EQ(JSFunction::kCodeEntryOffset, FieldAccessOf(node->op()).offset);
DCHECK(FieldAccessOf(node->op()).offset == JSFunction::kCodeEntryOffset ||
FieldAccessOf(node->op()).offset == Name::kHashFieldOffset);
val = slot_not_analyzed_;
}
if (object->GetField(offset) != val) {

View File

@ -3803,6 +3803,24 @@ Handle<Object> TranslatedState::MaterializeAt(int frame_index,
CHECK(next_link->IsUndefined(isolate_));
return object;
}
case CONS_STRING_TYPE: {
Handle<ConsString> object = Handle<ConsString>::cast(
isolate_->factory()
->NewConsString(isolate_->factory()->undefined_string(),
isolate_->factory()->undefined_string())
.ToHandleChecked());
slot->value_ = object;
Handle<Object> hash = MaterializeAt(frame_index, value_index);
Handle<Object> length = MaterializeAt(frame_index, value_index);
Handle<Object> first = MaterializeAt(frame_index, value_index);
Handle<Object> second = MaterializeAt(frame_index, value_index);
object->set_map(*map);
object->set_length(Smi::cast(*length)->value());
object->set_first(String::cast(*first));
object->set_second(String::cast(*second));
CHECK(hash->IsNumber()); // The {Name::kEmptyHashField} value.
return object;
}
case CONTEXT_EXTENSION_TYPE: {
Handle<ContextExtension> object =
isolate_->factory()->NewContextExtension(

View File

@ -0,0 +1,24 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --turbo --turbo-escape
function f(str) {
var s = "We turn {" + str + "} into a ConsString now";
return s.length;
}
assertEquals(33, f("a"));
assertEquals(33, f("b"));
%OptimizeFunctionOnNextCall(f);
assertEquals(33, f("c"));
function g(str) {
var s = "We also try to materalize {" + str + "} when deopting";
%DeoptimizeNow();
return s.length;
}
assertEquals(43, g("a"));
assertEquals(43, g("b"));
%OptimizeFunctionOnNextCall(g);
assertEquals(43, g("c"));