[deoptimizer] Make sure property arrays don't contain mutable heap numbers.
Since the deoptimizer generalizes maps for all materialized objects, it must make sure that none of the object's fields contain mutable heap numbers (only double fields are allowed to point to mutable heap numbers). With this CL, we simply change any mutable heap numbers in property arrays to immutable ones. This could be dangerous if some non-materialized object could point to this property array, but this cannot happen because interpreter registers cannot refer to naked property arrays. Bug: chromium:776309 Change-Id: I897b604fa804de673710cfa3ba0595dbd9f80eeb Reviewed-on: https://chromium-review.googlesource.com/759781 Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Commit-Queue: Jaroslav Sevcik <jarin@chromium.org> Cr-Commit-Position: refs/heads/master@{#49263}
This commit is contained in:
parent
c899637deb
commit
9eb92da618
@ -3229,10 +3229,32 @@ class TranslatedState::CapturedObjectMaterializer {
|
||||
int field_count)
|
||||
: state_(state), frame_index_(frame_index), field_count_(field_count) {}
|
||||
|
||||
// Ensure the properties never contain mutable heap numbers. This is necessary
|
||||
// because the deoptimizer generalizes all maps to tagged representation
|
||||
// fields (so mutable heap numbers are not allowed).
|
||||
static void EnsurePropertiesGeneralized(Handle<Object> properties_or_hash) {
|
||||
if (properties_or_hash->IsPropertyArray()) {
|
||||
Handle<PropertyArray> properties =
|
||||
Handle<PropertyArray>::cast(properties_or_hash);
|
||||
int length = properties->length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (properties->get(i)->IsMutableHeapNumber()) {
|
||||
Handle<HeapObject> box(HeapObject::cast(properties->get(i)));
|
||||
box->set_map(properties->GetIsolate()->heap()->heap_number_map());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Handle<Object> FieldAt(int* value_index) {
|
||||
CHECK_GT(field_count_, 0);
|
||||
--field_count_;
|
||||
return state_->MaterializeAt(frame_index_, value_index);
|
||||
Handle<Object> object = state_->MaterializeAt(frame_index_, value_index);
|
||||
// This is a big hammer to make sure that the materialized objects do not
|
||||
// have property arrays with mutable heap numbers (mutable heap numbers are
|
||||
// bad because we generalize maps for all materialized objects).
|
||||
EnsurePropertiesGeneralized(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
~CapturedObjectMaterializer() { CHECK_EQ(0, field_count_); }
|
||||
|
27
test/mjsunit/regress/regress-776309.js
Normal file
27
test/mjsunit/regress/regress-776309.js
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2017 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
|
||||
|
||||
function C() { }
|
||||
|
||||
function f(b) {
|
||||
var o = new C();
|
||||
// Create out-of-object properties only on one branch so that escape
|
||||
// analysis does not analyze the property array away.
|
||||
if (b) o.t = 1.1;
|
||||
%_DeoptimizeNow();
|
||||
return o.t;
|
||||
}
|
||||
|
||||
// Finish slack tracking for C.
|
||||
for (var i = 0; i < 1000; i++) new C();
|
||||
|
||||
f(true);
|
||||
f(true);
|
||||
f(false);
|
||||
|
||||
%OptimizeFunctionOnNextCall(f);
|
||||
|
||||
assertEquals(1.1, f(true));
|
Loading…
Reference in New Issue
Block a user